SpringBoot 整合Shiro 之 自定義Filter

結合上一篇 【Spring Boot 整合 Shiro】,第一次使用以後,但發現,Shiro過濾器對被 劫持 的API路徑,若沒「login.jsp」,則會直接返回 404 ,很不和諧。所以,搗鼓一下,自定義FIlter,經過自定義對其進行受權認證。java

項目源碼直通車git

1. 自定義 Filter

@Slf4j
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) {
            if (!isLoginSubmission(request, response)) {
                if (log.isTraceEnabled()) {
                    log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
                            "Authentication url [" + getLoginUrl() + "]");
                }

                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                httpServletResponse.setContentType("application/json;charset=UTF-8");
                httpServletResponse.setStatus(HttpStatus.CONFLICT.value());
                JSONObject json = new JSONObject();
                json.put("message","沒有權限訪問");
                Writer writer = httpServletResponse.getWriter();
                writer.write(json.toJSONString());
                writer.flush();
                writer.close();
            }else {
                return executeLogin(request, response);
            }
        }
        return false;
    }
}
複製代碼

根據Shiro默認的過濾器鏈,咱們能夠經過繼承,並將自身Filter添加到其過濾器鏈中github

anon(AnonymousFilter.class),
authc(FormAuthenticationFilter.class),
authcBasic(BasicHttpAuthenticationFilter.class),
logout(LogoutFilter.class),
noSessionCreation(NoSessionCreationFilter.class),
perms(PermissionsAuthorizationFilter.class),
port(PortFilter.class),
rest(HttpMethodPermissionFilter.class),
roles(RolesAuthorizationFilter.class),
ssl(SslFilter.class),
user(UserFilter.class);
複製代碼

2. 從新配置ShiroConfig

@Configuration
@ConfigurationProperties(prefix = "shiro")
public class ShiroConfig {

    private final static String AUTHC_STR = "authc";
    private final static String ANON_STR = "anon";

    @Getter
    @Setter
    private List<String> anon_uri;

    /** * 驗證受權、認證 * * @return shiroRealm 受權認證 */
    @Bean
    public ShiroRealm shiroRealm(){
        return new ShiroRealm();
    }

    /** * session manager * * @param shiroRealm 受權認證 * @return 安全管理 */
    @Bean
    @ConditionalOnClass(ShiroRealm.class)
    public SecurityManager securityManager(ShiroRealm shiroRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        return securityManager;
    }
    
    @Bean
    public CustomFormAuthenticationFilter customAuthenticationFilter(){
        return new CustomFormAuthenticationFilter();
    }

    /** * Filter工廠,設置對應的過濾條件和跳轉條件 * * @param securityManager session 管理 * @return shiro 過濾工廠 */
    @Bean
    @ConditionalOnClass(value = {CustomFormAuthenticationFilter.class,SecurityManager.class})
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, CustomFormAuthenticationFilter customAuthenticationFilter) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 自定義過濾器
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
        filterMap.put("restful_return", customAuthenticationFilter);

        shiroFilterFactoryBean.setFilters(filterMap);

        //URI過濾
        Map<String,String> map = Maps.newLinkedHashMap();
        
        //可過濾的接口路徑
        anon_uri.forEach(item -> map.put(item,ANON_STR));

        //全部路徑進行校驗
        map.put("/api/**",AUTHC_STR);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }


}
複製代碼

主要兩點:spring

2.1.注入CustomFormAuthenticationFilter

@Bean
public CustomFormAuthenticationFilter customAuthenticationFilter(){
	return new CustomFormAuthenticationFilter();
}
複製代碼

2.2 加入過濾器鏈

// 自定義過濾器
Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
filterMap.put("restful_return", customAuthenticationFilter);

shiroFilterFactoryBean.setFilters(filterMap);
複製代碼

3. 測試結果

相關文章
相關標籤/搜索