天天看點

從零開始搭建自己的網站二十八:springboot配置shiro權限,并在freemarker上進行權限控制

我們這裡通過shiro來進行權限控制,今天要講的就是在springboot中配置shiro。

1、引入shiro包

第一個是shiro的核心包,第二個是freemarker上使用shiro标簽的包

compile('org.apache.shiro:shiro-spring:1.3.2')
compile('net.mingsoft:shiro-freemarker-tags:0.1')
           

2、自定義CustomRealm

public class CustomRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(CustomRealm.class);

    @Autowired
    private UserService userService;

    /**
     * 擷取身份驗證資訊
     * Shiro中,最終是通過 Realm 來擷取應用程式中的使用者、角色及權限資訊的。
     *
     * @param authenticationToken 使用者身份資訊 token
     * @return 傳回封裝了使用者資訊的 AuthenticationInfo 執行個體
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("————身份認證方法————");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        // 從資料庫擷取對應使用者名密碼的使用者
        String password = userService.getPassword(token.getUsername());
        if (null == password) {
            throw new AccountException("使用者名不正确");
        } else if (!password.equals(new String((char[]) token.getCredentials()))) {
            throw new AccountException("密碼不正确");
        }
        return new SimpleAuthenticationInfo(token.getPrincipal(), password, getName());
    }

    /**
     * 擷取授權資訊
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("————權限認證————");
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //獲得該使用者角色
        String role = userService.getUserRole(username);
        logger.info(username + "的角色為:" + role);
        String[] split = role.split(",");
        Set<String> set = new HashSet<>();
        for (String ro : split) {
            //需要将 role 封裝到 Set 作為 info.setRoles() 的參數
            set.add(ro);
        }
        //設定該使用者擁有的角色
        info.setRoles(set);
        return info;
    }
}
           
/**
 * freemarker內建Shiro标簽
 */
@Component
public class ShiroTagFreeMarkerConfigurer implements InitializingBean {

    @Autowired
    private Configuration configuration;

    @Autowired
    private FreeMarkerViewResolver resolver;

    @Override
    public void afterPropertiesSet() throws Exception {
        // 加上這句後,可以在頁面上使用shiro标簽
        configuration.setSharedVariable("shiro", new ShiroTags());
        // 加上這句後,可以在頁面上用${context.contextPath}擷取contextPath
        resolver.setRequestContextAttribute("context");
    }
}
           
/**
 * shiro 權限配置類
 * Created by 493858256qq.com on 2019/8/9.
 */
@Configuration
public class ShiroConfig {

    private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必須設定 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // setLoginUrl 如果不設定值,預設會自動尋找Web工程根目錄下的"/login.jsp"頁面 或 "/login" 映射
        shiroFilterFactoryBean.setLoginUrl("/login/login");
        // 設定無權限時跳轉的 url;
        shiroFilterFactoryBean.setUnauthorizedUrl("/login/login");
        // 設定攔截器
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //遊客,開發權限
        filterChainDefinitionMap.put("/guest/**", "anon");
        //使用者,需要角色權限 “user”
        //管理者,需要角色權限 “admin”
        filterChainDefinitionMap.put("/manager/**", "roles[user]");
        //開放登陸接口
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        //其餘接口一律攔截
        //主要這行代碼必須放在所有權限設定的最後,不然會導緻所有 url 都被攔截
        filterChainDefinitionMap.put("/**", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        logger.info("Shiro攔截器工廠類注入成功");
        return shiroFilterFactoryBean;
    }

    /**
     * 注入 securityManager
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 設定realm.
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    /**
     * 自定義身份認證 realm;
     * <p>
     * 必須寫這個類,并加上 @Bean 注解,目的是注入 CustomRealm,
     * 否則會影響 CustomRealm類 中其他類的依賴注入
     */
    @Bean
    public CustomRealm customRealm() {
        return new CustomRealm();
    }
}
           

3、在html中使用shiro标簽來進行控制菜單顯示,比如admin角色可以顯示首頁

<@shiro.hasRole name="admin">
<li><a class="menu" href="index.html" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >首頁</a></li>
</@shiro.hasRole>
<li><a class="menu" href="index.html" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >個人資料</a></li>
           

歡迎轉載,轉載請注明出處 https://www.dingyinwu.com/article/74.html

如果文章中有任何問題或者可以改進的地方,請大家多提提意見,我會非常感激。

繼續閱讀