Shiro filters will return 404 for hijacked API paths without “login.jsp”. Shiro filters will return 404 for hijacked API paths without “login.jsp”. So let’s play around with custom filters and authorize them by customizing them.

Project source through train

1. Customize 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"."No access");
                Writer writer = httpServletResponse.getWriter();
                writer.write(json.toJSONString());
                writer.flush();
                writer.close();
            }else {
                returnexecuteLogin(request, response); }}return false; }}Copy the code

According to Shiro’s default Filter chain, we can inherit and add our own Filter to its Filter chain

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);
Copy the code

2. Reconfigure 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;

    /** * verify authorization and authentication@returnShiroRealm Authentication */
    @Bean
    public ShiroRealm shiroRealm(a){
        return new ShiroRealm();
    }

    /**
     * session manager
     *
     * @paramShiroRealm Authentication *@returnSafety management */
    @Bean
    @ConditionalOnClass(ShiroRealm.class)
    public SecurityManager securityManager(ShiroRealm shiroRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        return securityManager;
    }
    
    @Bean
    public CustomFormAuthenticationFilter customAuthenticationFilter(a){
        return new CustomFormAuthenticationFilter();
    }

    /** * Filter factory, set the corresponding Filter condition and jump condition **@paramSecurityManager Session Management *@returnShiro Filter Factory */
    @Bean
    @ConditionalOnClass(value = {CustomFormAuthenticationFilter.class,SecurityManager.class})
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, CustomFormAuthenticationFilter customAuthenticationFilter) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // Custom filters
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
        filterMap.put("restful_return", customAuthenticationFilter);

        shiroFilterFactoryBean.setFilters(filterMap);

        / / URI filter
        Map<String,String> map = Maps.newLinkedHashMap();
        
        // Filterable interface path
        anon_uri.forEach(item -> map.put(item,ANON_STR));

        // Verify all paths
        map.put("/api/**",AUTHC_STR);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        returnshiroFilterFactoryBean; }}Copy the code

Two main points:

2.1 injection CustomFormAuthenticationFilter

@Bean
public CustomFormAuthenticationFilter customAuthenticationFilter(a){
	return new CustomFormAuthenticationFilter();
}
Copy the code

2.2 Add filter chain

// Custom filters
Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
filterMap.put("restful_return", customAuthenticationFilter);

shiroFilterFactoryBean.setFilters(filterMap);
Copy the code

3. Test results