springboot 集成shiro ,简单演示jwt

1.首先集成maven依赖

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

2.自定义过滤器,获取token信息进行登陆

public class MyFilter extends BasicHttpAuthenticationFilter {

    //跨域处理
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
       // httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpServletResponse.setHeader("Access-control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
        response.setCharacterEncoding("utf-8");
        return super.preHandle(request, response);
    }

//这里看到暂时没有用到,之前看别人demo有用.
/*
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginSubmission(request, response)) {
                executeLogin(request, response);
        } else {
            HttpServletResponse response1 = (HttpServletResponse) response;
            try {
                response1.getWriter().write("no token");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
        return true;
    }*/

    //拒绝访问后回调到这里
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginAttempt(request, response)) {
            try{
                executeLogin(request, response);
            }catch (Exception e){
                HttpServletResponse response1 = (HttpServletResponse) response;
                try {
                    ObjectMapper ob = new ObjectMapper();
                    Map<String,Object> map = new HashMap<>();
                    map.put("msg", e.getMessage());  
                    map.put("code","201" );
                    String s = ob.writeValueAsString(map);
                    response1.getWriter().write(s);
                } catch (IOException ee) {
                    ee.printStackTrace();
                }
                return false;
            }
        } else {
            HttpServletResponse response1 = (HttpServletResponse) response;
            try {
                response1.getWriter().write("no token");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
        return super.onAccessDenied(request, response);
    }
    

    //是否具备登陆条件
    @Override
    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
        HttpServletRequest req = (HttpServletRequest) request;
        String authorization = req.getHeader("token");
        return authorization != null;
    }


    //进行登陆验证,如果失败getSubject将产生异常,抛到onAccessDenied进行捕获
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response)  {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String authorization = httpServletRequest.getHeader("token");
        MyToken token = new MyToken(authorization);
        getSubject(request, response).login(token);
        return true;
    }



    //登陆回调,这里没有调用subject.Login,所以用不到
    /*@Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        System.out.println("ddawdwadaawd");
        return super.onLoginFailure(token, e, request, response);
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        System.out.println("wadwa21313131111111111");
        return super.onLoginSuccess(token, subject, request, response);
    }*/
}

3.自定义token

public class MyToken implements AuthenticationToken {
    private String token;

    public MyToken(String token) {
        this.token = token;
    }

    @Override
    public Object getPrincipal() {
        return token;
    }

    @Override
    public Object getCredentials() {
        return token;
    }
}

4.自定义的realm

@Component
public class MyRealm extends AuthorizingRealm {

    //是否支持验证
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof MyToken;
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String token = (String) principalCollection.getPrimaryPrincipal();
        Set role = new HashSet();
        if (token.equals("123")) {
            role.add("admin");
        } else {
            role.add("guest");
        }
        Set perms = new HashSet();
        if (token.equals("123")) {
            perms.add("ddd");
        } else {
            perms.add("delete");
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(role);
        simpleAuthorizationInfo.addStringPermissions(perms);
        return simpleAuthorizationInfo;
    }

    //验证身份
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getPrincipal();
        if (token == null) {
            throw new AuthenticationException("没有jwt的token");
        }
        if (!token.equals("123") && !token.equals("111")) {
            throw new UnknownAccountException("验证失败");
        }
        return new SimpleAuthenticationInfo(token, token, "myRealm");
    }
}

5.shiro权限控制中心

@Configuration
public class MyShiroFilter {


    @Bean("shiroFilter")
    public ShiroFilterFactoryBean bean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
        Map<String, Filter> filters = bean.getFilters();
        filters.put("jwt", new MyFilter());
        filters.put("myRole", new RoleConfig());
        filters.put("myPerm", new PermConfig());
        Map<String, String> filterRuleMap = new HashMap<>();
        filterRuleMap.put("/login", "anon");
        filterRuleMap.put("/index", "jwt,myRole[admin]");
        filterRuleMap.put("/test", "jwt");
        filterRuleMap.put("/**", "jwt");
        bean.setFilterChainDefinitionMap(filterRuleMap);
        bean.setUnauthorizedUrl("/fail");
        return bean;
    }

    //安全管理器
    @Bean
    public DefaultWebSecurityManager manager(MyRealm realm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(realm);
        //这里设置不创建session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
        evaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(evaluator);
        manager.setSubjectDAO(subjectDAO);
        return manager;
    }

    /**
     * 下面的代码是添加注解支持
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        // 强制使用cglib,防止重复代理和可能引起代理出错的问题
        // https://zhuanlan.zhihu.com/p/29161098
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}

6.自定义的roles,perms过滤

public class PermConfig extends PermissionsAuthorizationFilter {
    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;
        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++) {
            if (subject.isPermitted(rolesArray[i])) {
                return true;
            }
        }
        return false;
    }
}
public class RoleConfig extends AuthorizationFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        Subject subject = this.getSubject(servletRequest, servletResponse);
        String[] rolesArray = (String[]) o;

        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++) {
            if (subject.hasRole(rolesArray[i])) {
                return true;
            }
        }
        return false;
    }
}

7.controller

@RestController
public class IndexController {

    @GetMapping("login")
    public Object login(@RequestParam(required = true) String name, @RequestParam(required = true) String pass) {
        if (name.equals("gao") && pass.equals("123")) {
            return "123";
        } else {
            throw new ExceptionA(2222,"登陆失败");
        }
    }


    @GetMapping("index")
    public Object index() {
        return "测试role";
    }

    @GetMapping("fail")
    public Object fail() {
        Map map = new HashMap<>();
        map.put("message", "授权失败");
        return map;
    }

    @RequiresPermissions(value = "delete")
    @GetMapping("test")
    public Object test() {
        return "测试资源";
    }
}

该demo过于简陋,并没有涉及到jwt,都将登陆信息写死了...但是思路是对的,在login接口中生成jwt的token,返给前端,然后后台带着token访问接口,拦截器拿到token,然后进行验证处理;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值