用spring security设置用户jwt令牌和设置接口访问权限案例


1.配置Swagger

为了方便测试首先在swagger config中配置加入令牌项,配置token作为请求头部参数:

@Configuration
@EnableSwagger2
public class SwaggerConfig
{
    
    
    /** 是否开启swagger */
    @Value("true")
    private boolean enabled;
    
    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi() {
    
    
        // 添加请求参数,我们这里把token作为请求头部参数传入后端
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        List<Parameter> parameters = new ArrayList<Parameter>();
        parameterBuilder.name("token").description("令牌")
                .modelRef(new ModelRef("string")).parameterType("header").required(false).build(); //关键是这里,将token作为了请求头参数
        parameters.add(parameterBuilder.build());
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(enabled)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.english.english_vision"))
                .paths(PathSelectors.any())
                .build().globalOperationParameters(parameters);
    }

    private ApiInfo apiInfo() {
    
    
       .....
    }
}

这样写了以后运行会发现在请求时多了一行token:
在这里插入图片描述
在登陆成功后会返回token,用这个token去请求其他接口即可

2.spring security配置

新建securityconfig类

@Primary
//由于报There is more than one bean of 'UserDetailsService' 所以我在类上面加了@primary 不过不加也不影响运行
@Configuration
@EnableWebSecurity    // 开启Spring Security
@EnableGlobalMethodSecurity(prePostEnabled = true)	// 开启权限注解,如:@PreAuthorize注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    

    @Autowired
    private UserDetailsService userDetailsService;
    //UserDetailsService 是rpingsecurity中自己的接口

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        // 使用自定义身份验证组件
        auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf
        http.cors().and().csrf().disable()
                .authorizeRequests()
                // 跨域预检请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/user/login").permitAll()//这里的路径可以自己配置
                .antMatchers("/security/save").permitAll()//注册
                .antMatchers("/security/login").permitAll()//登录
                // swagger
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/v2/api-docs").permitAll()
                .antMatchers("/webjars/springfox-swagger-ui/**").permitAll()
           
                // 服务监控
                .antMatchers("/actuator/**").permitAll()
                // 其他所有请求需要身份认证
                .anyRequest().authenticated();
        // 退出登录处理器
        http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
        // token验证过滤器
        http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
    
    
        return super.authenticationManager();
    }

}

3.用户校验逻辑

spring security整合jwt的代码较多,目录如下:
在这里插入图片描述

注册和登录接口

@RestController
@RequestMapping("/security")
@Api(tags = {
    
    "安全登录接口"})
public class UserSecurityController {
    
    
    @Autowired
    private IUserSecurityService securityService;
    @Autowired
    private AuthenticationManager authenticationManager;

    @ApiOperation(value = "注册或者修改用户")
    @PostMapping(value = "/save")
    public ResponseResult save(UserSecurity record) {
    
    
        boolean save=false;
        UserSecurity userSecurity = securityService.getById(record.getId());
        if (record.getPassword() != null) {
    
    
            String salt = PasswordUtils.getSalt();
            if (userSecurity == null) {
    
    
                // 新增用户

                if (securityService.selectByName(record.getName()) != null) {
    
    
                    return ResponseResult.error("用户名已存在!");
                }
                String password = PasswordUtils.encode(record.getPassword(), salt);               
                record.setSalt(salt);
                record.setPassword(password);
            } else {
    
    
                // 修改用户, 且修改了密码
                if (!record.getPassword().equals(userSecurity.getPassword())) {
    
    
                    String password = PasswordUtils.encode(record.getPassword(), salt);
                    record.setSalt(salt);
                    record.setPassword(password);
                }
            }
           save = securityService.save(record);

        }
        if (save) {
    
    
            return ResponseResult.success(record);
        } else {
    
    
            return ResponseResult.error(ResponseEnum.ERROR);
        }
    }
    @ApiOperation(value = "用户登录")
    @PostMapping(value = "/login")
    public ResponseResult login(@RequestBody LoginBean loginBean, HttpServletRequest request)
    {
    
    
        String username = loginBean.getName();
        String password = loginBean.getPassword();
// 用户信息
        UserSecurity user = securityService.selectByName(username);
        // 账号不存在、密码错误
        if (user == null) {
    
    
            return ResponseResult.error("账号不存在");
        }     
        if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) {
    
    
            return ResponseResult.error("密码不正确");
        }
        // 系统登录认证
        JwtAuthenticatioToken token = SecurityUtils.login(request, username, password, authenticationManager);
        return ResponseResult.success(token);
    }
}


加密是:
String password = PasswordUtils.encode(record.getPassword(), salt);
验证是:
if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) {
}
加密时只会对明文密码进行加密然后与数据库进行匹配,不会对密文解密,这样更加安全。

dao层 service层 pojo层

public interface IUserSecurityService extends IService<UserSecurity> {
    
    
    UserSecurity selectByName(String username);
    Set<String> findPermissions(String userName);
}

@Service
public class UserSecurityServiceImpl extends ServiceImpl<UserSecurityMapper, UserSecurity> implements IUserSecurityService {
    
    
@Autowired
private UserSecurityMapper securityMapper;
    @Override
    public UserSecurity selectByName(String username) {
    
    
        return securityMapper.selectByName(username);
    }

    @Override
    public Set<String> findPermissions(String userName) {
    
    
        return securityMapper.findPermissions(userName);
    }
}

loginbean:

/**
 * @Author
 * @Description 登录接口封装对象
 * @Date
 **/
@Data
public class LoginBean {
    
    
    private String name;
    private String password;
   // private String captcha;

}

用户pojo:

@NoArgsConstructor
@AllArgsConstructor
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user_security")
@ApiModel("用户安全管理")
public class UserSecurity implements Serializable {
    
    

    private static final long serialVersionUID = 1L;
    @ApiModelProperty(name = "id", value = "用户id", dataType = "Integer")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id=null;
    @ApiModelProperty(name = "name", value = "用户名", dataType = "String")
    private String name;
    @ApiModelProperty(name = "password", value = "用户密码", dataType = "String")
    private String password;
    @ApiModelProperty(name = "salt", value = "密码盐", dataType = "String")
    private String salt;
    @ApiModelProperty(name = "perm", value = "用户权限", dataType = "String")
    private String perm;
}

mapper:

@Mapper
public interface UserSecurityMapper extends BaseMapper<UserSecurity> {
    
    

    @Select("select * from t_user_security where name=#{username}")
    UserSecurity selectByName(String username);
    @Select("select perm from t_user_security where name=#{username}")
    Set<String> findPermissions(String userName);
}

4.加密验证逻辑

/**
 * 密码工具类
 */
public class PasswordUtils {
    
    

	/**
	 * 匹配密码
	 * @param salt 盐
	 * @param rawPass 明文 
	 * @param encPass 密文
	 * @return
	 */
	public static boolean matches(String salt, String rawPass, String encPass) {
    
    
		return new PasswordEncoder(salt).matches(encPass, rawPass);
	}
	
	/**
	 * 明文密码加密
	 * @param rawPass 明文
	 * @param salt
	 * @return
	 */
	public static String encode(String rawPass, String salt) {
    
    
		return new PasswordEncoder(salt).encode(rawPass);
	}

	/**
	 * 获取加密盐
	 * @return
	 */
	public static String getSalt() {
    
    
		return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
	}
}

加密:

public class PasswordEncoder {
    
    

	private final static String[] hexDigits = {
    
     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
			"e", "f" };

	private final static String MD5 = "MD5";
	private final static String SHA = "SHA";
	
	private Object salt;
	private String algorithm;

	public PasswordEncoder(Object salt) {
    
    
		this(salt, MD5);
	}
	
	public PasswordEncoder(Object salt, String algorithm) {
    
    
		this.salt = salt;
		this.algorithm = algorithm;
	}

	/**
	 * 密码加密
	 * @param rawPass
	 * @return
	 */
	public String encode(String rawPass) {
    
    
		String result = null;
		try {
    
    
			System.out.println("加密"+rawPass);
			MessageDigest md = MessageDigest.getInstance(algorithm);
			// 加密后的字符串
			result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes("utf-8")));
		} catch (Exception ex) {
    
    
		}
		return result;
	}

	/**
	 * 密码匹配验证
	 * @param encPass 密文
	 * @param rawPass 明文
	 * @return
	 */
	public boolean matches(String encPass, String rawPass) {
    
    
		String pass1 = "" + encPass;
		String pass2 = encode(rawPass);
		System.out.println("密文"+encPass);
		System.out.println(rawPass+"加密后"+pass2);
		return pass1.equals(pass2);
	}

	private String mergePasswordAndSalt(String password) {
    
    
		if (password == null) {
    
    
			password = "";
		}

		if ((salt == null) || "".equals(salt)) {
    
    
			return password;
		} else {
    
    
			return password + "{" + salt.toString() + "}";
		}
	}

	/**
	 * 转换字节数组为16进制字串
	 * 
	 * @param b
	 *            字节数组
	 * @return 16进制字串
	 */
	private String byteArrayToHexString(byte[] b) {
    
    
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
    
    
			resultSb.append(byteToHexString(b[i]));
		}
		return resultSb.toString();
	}

	/**
	 * 将字节转换为16进制
	 * @param b
	 * @return
	 */
	private static String byteToHexString(byte b) {
    
    
		int n = b;
		if (n < 0)
			n = 256 + n;
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

5.生成令牌逻辑

身份验证提供者:

package com.english.english_vision.config.springSecurity;

import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;


/**
 * @Author
 * @Description 身份验证提供者
 * @Date 10.19
 **/
public class JwtAuthenticationProvider extends DaoAuthenticationProvider {
    
    

    public JwtAuthenticationProvider(UserDetailsService userDetailsService) {
    
    
        setUserDetailsService(userDetailsService);
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
    
    
        if (authentication.getCredentials() == null) {
    
    
            logger.debug("Authentication failed: no credentials provided");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        }

        String presentedPassword = authentication.getCredentials().toString();
        String salt = ((JwtUserDetails) userDetails).getSalt();
        // 覆写密码验证逻辑
        if (!new PasswordEncoder(salt).matches(userDetails.getPassword(), presentedPassword)) {
    
    
            logger.debug("Authentication failed: password does not match stored value");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        }
    }

}

自定义令牌对象:

package com.english.english_vision.config.springSecurity;

import java.util.Collection;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;


public class JwtAuthenticatioToken extends UsernamePasswordAuthenticationToken {
    
    

	private static final long serialVersionUID = 1L;
	
	private String token;

    public JwtAuthenticatioToken(Object principal, Object credentials){
    
    
        super(principal, credentials);
    }
    
    public JwtAuthenticatioToken(Object principal, Object credentials, String token){
    
    
    	super(principal, credentials);
    	this.token = token;
    }

    public JwtAuthenticatioToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities, String token) {
    
    
    	super(principal, credentials, authorities);
    	this.token = token;
    }
    
	public String getToken() {
    
    
		return token;
	}

	public void setToken(String token) {
    
    
		this.token = token;
	}

	public static long getSerialversionuid() {
    
    
		return serialVersionUID;
	}

}

JwtAuthenticatioToken继承自UsernamePasswordAuthenticationToken,
UsernamePasswordAuthenticationToken继承AbstractAuthenticationToken实现Authentication
所以当在页面中输入用户名和密码之后首先会进入到UsernamePasswordAuthenticationToken验(Authentication),
然后生成的Authentication会被交由AuthenticationManager来进行管理,而AuthenticationManager管理一系列的AuthenticationProvider,每一个Provider都会通UserDetailsService和UserDetail来返回一个以UsernamePasswordAuthenticationToken实现的带用户名和密码以及权限的Authentication

6.登录认证过滤器:

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
    
    

	
	@Autowired
    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
    
    
        super(authenticationManager);
    }
//AuthenticationManager这个接口方法入参和返回值的类型都是Authentication。该接口的作用是对用户的未授信凭据进行认证,认证通过则返回授信状态的凭据,否则将抛出认证异常AuthenticationException。
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
    	// 获取token, 并检查登录状态
        SecurityUtils.checkAuthentication(request);
        chain.doFilter(request, response);
    }
    
}

BasicAuthenticationFilter:当一个HTTP请求中包含一个名字为Authorization的头部,并且其值格式是Basic xxx时,该Filter会认为这是一个BASIC authorization头部,其中xxx部分应该是一个base64编码的{username}:{password}字符串。比如用户名/密码分别为 admin/secret, 则对应的该头部是 : Basic YWRtaW46c2VjcmV0 。

该过滤器会从 HTTP BASIC authorization头部解析出相应的用户名和密码然后调用AuthenticationManager进行认证,成功的话会把认证了的结果写入到SecurityContextHolder中SecurityContext的属性authentication上面。同时还会做其他一些处理,比如Remember Me相关处理等等。

7.JwtToken工具类:

public class JwtTokenUtils implements Serializable {
    
    

	private static final long serialVersionUID = 1L;
	
	/**
	 * 用户名称
	 */
	private static final String USERNAME = Claims.SUBJECT;
	/**
	 * 创建时间
	 */
	private static final String CREATED = "created";
	/**
	 * 权限列表
	 */
	private static final String AUTHORITIES = "authorities";
	/**
     * 密钥
     */
    private static final String SECRET = "abcdefgh";
    /**
     * 有效期12小时
     */
    private static final long EXPIRE_TIME = 12 * 60 * 60 * 1000;

    /**
	 * 生成令牌
	 *
	 * @param userDetails 用户
	 * @return 令牌
	 */
	public static String generateToken(Authentication authentication) {
    
    
	    Map<String, Object> claims = new HashMap<>(3);
	    claims.put(USERNAME, SecurityUtils.getUsername(authentication));
	    claims.put(CREATED, new Date());
	    claims.put(AUTHORITIES, authentication.getAuthorities());
	    return generateToken(claims);
	}

	/**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    private static String generateToken(Map<String, Object> claims) {
    
    
        Date expirationDate = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, SECRET).compact();
    }

    /**
	 * 从令牌中获取用户名
	 *
	 * @param token 令牌
	 * @return 用户名
	 */
	public static String getUsernameFromToken(String token) {
    
    
	    String username;
	    try {
    
    
	        Claims claims = getClaimsFromToken(token);
	        username = claims.getSubject();
	    } catch (Exception e) {
    
    
	        username = null;
	    }
	    return username;
	}
	
	/**
	 * 根据请求令牌获取登录认证信息
	 * @param token 令牌
	 * @return 用户名
	 */
	public static Authentication getAuthenticationeFromToken(HttpServletRequest request) {
    
    
		Authentication authentication = null;
		// 获取请求携带的令牌
		String token = JwtTokenUtils.getToken(request);
		if(token != null) {
    
    
			// 请求令牌不能为空
			if(SecurityUtils.getAuthentication() == null) {
    
    
				// 上下文中Authentication为空
				Claims claims = getClaimsFromToken(token);
				if(claims == null) {
    
    
					return null;
				}
				String username = claims.getSubject();
				if(username == null) {
    
    
					return null;
				}
				if(isTokenExpired(token)) {
    
    
					return null;
				}
				Object authors = claims.get(AUTHORITIES);
				List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
				if (authors != null && authors instanceof List) {
    
    
					for (Object object : (List) authors) {
    
    
						authorities.add(new GrantedAuthorityImpl((String) ((Map) object).get("authority")));
					}
				}
				authentication = new JwtAuthenticatioToken(username, null, authorities, token);
			} else {
    
    
				if(validateToken(token, SecurityUtils.getUsername())) {
    
    
					// 如果上下文中Authentication非空,且请求令牌合法,直接返回当前登录认证信息
					authentication = SecurityUtils.getAuthentication();
				}
			}
		}
		return authentication;
	}

	/**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private static Claims getClaimsFromToken(String token) {
    
    
        Claims claims;
        try {
    
    
            claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e) {
    
    
            claims = null;
        }
        return claims;
    }

    /**
	 * 验证令牌
	 * @param token
	 * @param username
	 * @return
	 */
	public static Boolean validateToken(String token, String username) {
    
    
	    String userName = getUsernameFromToken(token);
	    return (userName.equals(username) && !isTokenExpired(token));
	}

	/**
	 * 刷新令牌
	 * @param token
	 * @return
	 */
	public static String refreshToken(String token) {
    
    
	    String refreshedToken;
	    try {
    
    
	        Claims claims = getClaimsFromToken(token);
	        claims.put(CREATED, new Date());
	        refreshedToken = generateToken(claims);
	    } catch (Exception e) {
    
    
	        refreshedToken = null;
	    }
	    return refreshedToken;
	}

	/**
     * 判断令牌是否过期
     *
     * @param token 令牌
     * @return 是否过期
     */
    public static Boolean isTokenExpired(String token) {
    
    
        try {
    
    
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
    
    
            return false;
        }
    }

    /**
     * 获取请求token
     * @param request
     * @return
     */
    public static String getToken(HttpServletRequest request) {
    
    
    	String token = request.getHeader("Authorization");
        String tokenHead = "Bearer ";
        if(token == null) {
    
    
        	token = request.getHeader("token");
        } else if(token.contains(tokenHead)){
    
    
        	token = token.substring(tokenHead.length());
        } 
        if("".equals(token)) {
    
    
        	token = null;
        }
        return token;
    }

}

security工具类

public class SecurityUtils {
    
    

	/**
	 * 系统登录认证
	 * @param request
	 * @param username
	 * @param password
	 * @param authenticationManager
	 * @return
	 */
	public static JwtAuthenticatioToken login(HttpServletRequest request, String username, String password, AuthenticationManager authenticationManager) {
    
    
		JwtAuthenticatioToken token = new JwtAuthenticatioToken(username, password);
		token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
		// 执行登录认证过程
	    Authentication authentication = authenticationManager.authenticate(token);
	    // 认证成功存储认证信息到上下文
	    SecurityContextHolder.getContext().setAuthentication(authentication);
		// 生成令牌并返回给客户端
	    token.setToken(JwtTokenUtils.generateToken(authentication));
		return token;
	}

	/**
	 * 获取令牌进行认证
	 * @param request
	 */
	public static void checkAuthentication(HttpServletRequest request) {
    
    
		// 获取令牌并根据令牌获取登录认证信息
		Authentication authentication = JwtTokenUtils.getAuthenticationeFromToken(request);
		// 设置登录认证信息到上下文
		SecurityContextHolder.getContext().setAuthentication(authentication);
	}

	/**
	 * 获取当前用户名
	 * @return
	 */
	public static String getUsername() {
    
    
		String username = null;
		Authentication authentication = getAuthentication();
		if(authentication != null) {
    
    
			Object principal = authentication.getPrincipal();
			if(principal != null && principal instanceof UserDetails) {
    
    
				username = ((UserDetails) principal).getUsername();
			}
		}
		return username;
	}
	
	/**
	 * 获取用户名
	 * @return
	 */
	public static String getUsername(Authentication authentication) {
    
    
		String username = null;
		if(authentication != null) {
    
    
			Object principal = authentication.getPrincipal();
			if(principal != null && principal instanceof UserDetails) {
    
    
				username = ((UserDetails) principal).getUsername();
			}
		}
		return username;
	}
	
	/**
	 * 获取当前登录信息
	 * @return
	 */
	public static Authentication getAuthentication() {
    
    
		if(SecurityContextHolder.getContext() == null) {
    
    
			return null;
		}
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		return authentication;
	}
	
}

8.权限封装:

public class GrantedAuthorityImpl implements GrantedAuthority {
    
    
	
	private static final long serialVersionUID = 1L;

	private String authority;

    public GrantedAuthorityImpl(String authority) {
    
    
        this.authority = authority;
    }

    public void setAuthority(String authority) {
    
    
        this.authority = authority;
    }

    @Override
    public String getAuthority() {
    
    
        return this.authority;
    }
}

9.用户模型:

public class JwtUserDetails implements UserDetails {
    
    

	private static final long serialVersionUID = 1L;
	
	private String username;
    private String password;
    private String salt;
    private Collection<? extends GrantedAuthority> authorities;

    JwtUserDetails(String username, String password, String salt, Collection<? extends GrantedAuthority> authorities) {
    
    
        this.username = username;
        this.password = password;
        this.salt = salt;
        this.authorities = authorities;
    }

    @Override
    public String getUsername() {
    
    
        return username;
    }

    @JsonIgnore
    @Override
    public String getPassword() {
    
    
        return password;
    }

    public String getSalt() {
    
    
		return salt;
	}
    
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
    
    
        return authorities;
    }

    @JsonIgnore
    @Override
    public boolean isAccountNonExpired() {
    
    
        return true;
    }

    @JsonIgnore
    @Override
    public boolean isAccountNonLocked() {
    
    
        return true;
    }

    @JsonIgnore
    @Override
    public boolean isCredentialsNonExpired() {
    
    
        return true;
    }

    @JsonIgnore
    @Override
    public boolean isEnabled() {
    
    
        return true;
    }
}

10.测试生成令牌

配置好以后先注册:
在这里插入图片描述
返回注册成功的信息:
在这里插入图片描述
然后测试登录:
在这里插入图片描述
结果:
在这里插入图片描述
可以看到返回的token,复制下来然后用这个token测试其他接口即可

11.测试用户权限

首先在不加权限注解时测试这个接口:

    @ApiOperation(value="管理员添加某个单词")
    @PostMapping("admin/uploadword")
    public ResponseResult uploadWord(@RequestParam("wordfile")MultipartFile file,Word word) throws IOException {
    
    
        System.out.println("my CopyrightYear:"+new Myconfig().getCopyrightYear());
    String Wordpath = uploadUtils.upload(new Myconfig().getWordPath(),file);
word.setImg(Wordpath);
if(wordService.insert(word)>0)
{
    
    
    return ResponseResult.success(word);
}
else {
    
    
    return ResponseResult.error(ResponseEnum.ERROR);
}
    }

用刚刚生成的令牌进行测试:
在这里插入图片描述
可以看到添加成功:
在这里插入图片描述
现在在这个接口方法上加上权限注解:
@PreAuthorize(“hasAuthority(‘sys::manage’)”) ,重新运行:
由于刚刚登录的用户权限是sys::use,所以无法访问这个接口:
在这里插入图片描述
现在重新登录一个有sys::manage权限的用户,获得token,再次访问这个接口:

在这里插入图片描述

访问成功。

参考:https://blog.csdn.net/andy_zhang2007/article/details/84920910

https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1319904585363980289&__biz=MzUzMzQ2MDIyMA==#wechat_redirect

猜你喜欢

转载自blog.csdn.net/qq_41358574/article/details/120845859
今日推荐