用户认证+权限控制

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_40693828/article/details/102772394

采用的是springboot+Jwt+shiro,其实也可以采用spring-security-oauth来实现。
有没用到数据库,是在代码中给用户创建的假设的角色和权限

1 JWT工具类:
package com.irootech.bean;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

public class JwtUtil {


    /**
     * @description :生产token
     * @param username : 账户
     * @param pwd : 密码
     * @return :java.lang.String
     */
    public static String createToken(String username, String pwd){
        Algorithm algorithm=Algorithm.HMAC256(pwd);
        return  JWT.create().withClaim("username",username).sign(algorithm);
    }

    /**
     * @description :根据token获取用户名
     * @param token :
     * @return :java.lang.String
     */
    public static String getUsername(String token){
        DecodedJWT decodedJWT=JWT.decode(token);
        return decodedJWT.getClaim("username").asString();
    }
}


2 shiro的配置类:
package com.irootech.config;

import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author anping.tan
 * @date 2019/7/26 19:27
 */
@Configuration
public class ShiroConfig {


       @Bean
      public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, Filter> filtersMap = shiroFilterFactoryBean.getFilters();
        filtersMap.put("jwt", new ShiroFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);
        Map map=new HashMap();
        map.put("/static/**","anon");
        map.put("/**","jwt");
        map.put("/index","anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setUnauthorizedUrl("/403.action");
        return  shiroFilterFactoryBean;
    }

    @Bean
   public   UserInfoRealm userInfoRealm(){
           UserInfoRealm userInfoRealm=new UserInfoRealm();
           return  userInfoRealm;
   }
   @Bean
    public SecurityManager securityManager(UserInfoRealm userInfoRealm){
       DefaultSecurityManager  defaultSecurityManager=new DefaultWebSecurityManager();
       defaultSecurityManager.setRealm(userInfoRealm);
       return defaultSecurityManager;
    }


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


    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("UnauthorizedException","403");
        r.setExceptionMappings(mappings);  
        r.setDefaultErrorView("error");
        return r;
    }

}


3 实现AuthenticationToken 将内容值全部设为token:
package com.irootech.config;

import org.apache.shiro.authc.AuthenticationToken;

public class JwtToken implements AuthenticationToken {
    private String token;

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

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

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

4 定义拦截器:如果不存在Authorization则第一次登陆,直接进去控制器,返回token,下次再请求通过请求头携带着,下次通过入getSubject(request,response).login(jwtToken)进入realm;
package com.irootech.config;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;

import javax.naming.AuthenticationException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ShiroFilter extends BasicHttpAuthenticationFilter {
    @Override
    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
        HttpServletRequest req = (HttpServletRequest) request;
        String authorization = req.getHeader("Authorization");
        return authorization != null;
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest= (HttpServletRequest) request;
        String token=httpServletRequest.getHeader("Authorization");
       JwtToken jwtToken=new JwtToken(token);
        getSubject(request,response).login(jwtToken);
        return true;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginAttempt(request, response)) {
            try {
                executeLogin(request, response);
            } catch (Exception e) {
               throw new AuthorizationException("权限不足");
            }
        }
        return true;
    }
}


5 实现自定义realm  
package com.irootech.config;

import com.irootech.bean.JwtUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;


public class UserInfoRealm extends AuthorizingRealm {


    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof  JwtToken;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username= (String) authenticationToken.getCredentials();
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(username,username,getName());
        return simpleAuthenticationInfo;
    }


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        //获取用户名
        Object username= JwtUtil.getUsername(principalCollection.toString());
        //通过数据库的用户名,查询出用户拥有的角色和权限,假设权限有1,2
        simpleAuthorizationInfo.addStringPermission("1");
        simpleAuthorizationInfo.addStringPermission("2");
        return simpleAuthorizationInfo;
    }

}

6 控制层代码:通过加入注解来对接口的权限访问
package com.irootech.controller;

import com.irootech.bean.*;
import com.irootech.service.RolePerssionService;
import com.irootech.service.RoleService;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @author anping.tan
 * @date 2019/7/26 17:43
 */
@Controller
public class RoleController {

    @RequestMapping("/add.action")
    @RequiresPermissions("1")
   //跳转到add.html界面
    public String  add(){
        return "add";

    }

    @RequestMapping("/delete.action")
    @RequiresPermissions("3")
    //跳转到del.html界面
    public String  delete(){
        return "del";
    }

    @RequestMapping("/login.action")
    @ResponseBody
     public String login(HttpServletRequest request,String username,String password){
        User user=new User();
        user.setUsername("zhangsan");
        user.setPassword("a");
        String token= JwtUtil.createToken(username,password);
        return token;

    }

    @RequestMapping("/403.action")
    //跳转到403界面
    public String unfind(){
        return "403";
    }
  
    @RequestMapping("/update.action")
    @RequiresPermissions("2")
    //跳转到update.html界面
    public String update(){
        return "update";
    }


}

猜你喜欢

转载自blog.csdn.net/qq_40693828/article/details/102772394