Shiro添加自己的Filter

来源:互联网 发布:苹果变音软件 编辑:程序博客网 时间:2024/06/05 19:19

因为前后端分离,添加了自己的过滤器,根据cookie判断传过来的uuid是否是登录的token

使用到了cache,稍后会加上源码也稍后上传

ShiroConfiguration
@Beanpublic ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {    //这里设置了自己的过滤器    ShiroFilterFactoryBean shiroFilter = new CustomShiroFilterFactoryBean();    shiroFilter.setSecurityManager(securityManager);    shiroFilter.setLoginUrl("/auth.html");    shiroFilter.setUnauthorizedUrl("/403.html");    Map<String, String> filterMap = new LinkedHashMap<>();    //开放swagger资源 start    filterMap.put("/v2/api-docs", "anon");    filterMap.put("/webjars/**", "anon");    filterMap.put("/swagger-resources/**", "anon");    filterMap.put("/swagger-ui.html", "anon");    //开放swagger资源 end    filterMap.put("/api/**", "anon");    filterMap.put("/assets/**", "anon");    filterMap.put("/fonts/**", "anon");    filterMap.put("/maps/**", "anon");    filterMap.put("/api/_devops_/init", "anon");    filterMap.put("/configuration/ui", "anon");    filterMap.put("/configuration/security", "anon");    filterMap.put("/scripts/**", "anon");    filterMap.put("/styles/**", "anon");    filterMap.put("/auth.html", "anon");    filterMap.put("/index.html", "anon");    filterMap.put("/**", "authc");    shiroFilter.setFilterChainDefinitionMap(filterMap);    return shiroFilter;}


CustomShiroFilterFactoryBean

public class CustomShiroFilterFactoryBean extends ShiroFilterFactoryBean {    public static final String UUID_HEADER = "uuid";    private static final Pattern resourceSuffix = Pattern.compile("\\.\\w{1,15}$");    @Autowired    private CacheService cacheService;    @Override    protected AbstractShiroFilter createInstance() throws Exception {        // TODO Auto-generated method stub        FilterChainManager manager = createFilterChainManager();        // Expose the constructed FilterChainManager by first wrapping        // it in a        // FilterChainResolver implementation. The AbstractShiroFilter        // implementations        // do not know about FilterChainManagers - only resolvers:        PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();        chainResolver.setFilterChainManager(manager);        AbstractShiroFilter filter = new AbstractShiroFilter() {            protected boolean pathMatches(String pattern, String path) {                PatternMatcher pathMatcher = chainResolver.getPathMatcher();                return pathMatcher.matches(pattern, path);            }            protected boolean isRequestIgnored(ServletRequest request, ServletResponse response) {                if (!manager.hasChains()) {                    return false;                }                String requestURI = WebUtils.getPathWithinApplication(WebUtils.toHttp(request));                SimpleNamedFilterList configuredFilter = null;                Object anonFilter = null;                for (String pathPattern : manager.getChainNames()) {                    // If the path does match, then pass on to the subclass implementation for specific checks:                    if (pathMatches(pathPattern, requestURI)) {                        configuredFilter = (SimpleNamedFilterList) manager.getChain(pathPattern);                        break;                    }                }                if(configuredFilter != null && !configuredFilter.isEmpty()){                    anonFilter = configuredFilter.get(0);                }                if(anonFilter != null && anonFilter instanceof AnonymousFilter){                    return true;                }else{                    HttpServletRequest hsr = (HttpServletRequest) request;                    // bypass resource                    if ("GET".equalsIgnoreCase(hsr.getMethod()) && (resourceSuffix.matcher(hsr.getRequestURI()).find() || "/".equals(hsr.getRequestURI()))){                        return true;                    }                    return false;                }            }            @Override            protected WebSubject createSubject(ServletRequest request, ServletResponse response) {                WebSubject ws = super.createSubject(request, response);                if(isRequestIgnored(request,response)){                    return ws;                }                if(request instanceof HttpServletRequest == false){                    throw new RuntimeException("Inner error. The request is not a HttpServletRequest");                }                HttpServletRequest hsr = (HttpServletRequest)request;                String uuid = hsr.getHeader(UUID_HEADER);                if (uuid != null && !uuid.isEmpty()) {                    String cache = cacheService.getValue(uuid);                    if(cache == null || cache == ""){                        throw new AuthenticationException("uuid is illegal.");                    }                    String cache_uuid = cache.split("_")[0];                    String userId = cache.split("_")[1];                    String username = cache.split("_")[2];                    String password = cache.split("_")[3];                    UsernamePasswordToken token = new UsernamePasswordToken(username, password);                    if(!cache_uuid.equals(uuid)){                        throw new AuthenticationException("uuid is illegal.");                    }                    try {                        ws.login(token);                    } catch (AuthenticationException e) {                        throw new RuntimeException("Inner error. Failed to login with shiro.");                    }                } else {                    throw new ExceptionResponse("no "+UUID_HEADER+" header assigned");                }                return ws;            }        };        filter.setSecurityManager((WebSecurityManager) getSecurityManager());        filter.setFilterChainResolver(chainResolver);        return filter;    }}
LoginController

@RequestMapping(value = "/login",method = RequestMethod.POST)    @ApiOperation(value = "用户登录",notes = "根据用户名密码判断用户")    @ApiImplicitParam(value = "Map",required = true,dataType = "Map")    public Map<String,Object> login(@RequestBody Map<String, String> map) {        Map<String , Object> resurt = new HashMap<>();        UsernamePasswordToken token = null;        try {            String username = map.get("username");            //sha256加密            String password = new Sha256Hash(map.get("password")).toHex();            User user = userService.findByUserName(username);//      账号不存在        if(user == null) {            throw new ExceptionResponse("用户名不正确");        }        //密码错误        if(!password.equals(user.getPassword())) {            throw new ExceptionResponse("密码不正确");        }        //账号禁用        if("0".equals(user.getStatus())){            throw new ExceptionResponse("用户已被禁用,请联系管理员");        }            Subject subject = ShiroUtils.getSubject();            token = new UsernamePasswordToken(username, password);            String uuid = UUIDGenerator.creatUUID();            resurt.put("uuid",uuid);            cacheService.setValue(uuid,uuid + "_" + user.getId() + "_" + user.getUsername() + "_" + user.getPassword());            subject.login(token);        }catch (Exception e){            System.out.println(e);        }        return resurt;    }

测试:

1.没登陆:


2.登录 : 


将返回的uuid设置到header中


整合shiro可以参考:http://blog.csdn.net/a295277302/article/details/77454119

ShiroFilterFactoryBean源码及拦截原理深入分析:http://blog.csdn.net/u012345283/article/details/44199791


原创粉丝点击