html jwt权限控制,SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制
在整合jwt之前,我们首先要在SpringBoot中整合security的模块,来实现基于security的授权控制。用过security的人都知道,它的功能无比的强大比shiro还要强大,但是今天我就介绍security中关于权限控制和是登录验证的这一块的功能。
1.在开始之前我们先在pom.xml中添加security和jwt的相关依赖,如下所示:
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.sang
test26-security
0.0.1-SNAPSHOT
jar
Test26-Security
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.4.3.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-test
test
org.thymeleaf.extras
thymeleaf-extras-springsecurity4
mysql
mysql-connector-java
5.1.40
io.jsonwebtoken
jjwt
0.9.0
org.springframework.boot
spring-boot-maven-plugin
2.在application.properties中添加数据库和jpa还有jwt的相关配置。具体如下所示:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/security_db?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=220316
logging.level.org.springframework.security=info
spring.thymeleaf.cache=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
# JWT 604800
jwt.header:Authorization
jwt.secret:mySecret
jwt.expiration:10
jwt.tokenHead:Bearer
jwt.route.authentication.path:auth/login
jwt.route.authentication.refresh:auth/refresh
jwt.route.authentication.register:"auth/register"3.新建实体类,进行用户登录的授权验证。(这里我新建两个实体类,一个是用户实体类,一个是用户关系实体类)
用户实体类:SysUser
package org.security.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@Entity
public class SysUser implements UserDetails{
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
private Date lastPasswordResetDate;
@ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
private List roles;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public void setUsername(String username){
this.username = username;
}
public void setPassword(String password){
this.password = password;
}
public List getRoles(){
return roles;
}
public void setRoles(List roles){
this.roles = roles;
}
public Date getLastPasswordResetDate(){
return lastPasswordResetDate;
}
public void setLastPasswordResetDate(Date lastPasswordResetDate){
this.lastPasswordResetDate = lastPasswordResetDate;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
List auths = new ArrayList<>();
List roles = this.getRoles();
for (SysRole role : roles) {
auths.add(new SimpleGrantedAuthority(role.getName()));
}
return auths;
}
@Override
public String getPassword(){
return this.password;
}
@Override
public String getUsername(){
return this.username;
}
@Override
public boolean isAccountNonExpired(){
return true;
}
@Override
public boolean isAccountNonLocked(){
return true;
}
@Override
public boolean isCredentialsNonExpired(){
return true;
}
@Override
public boolean isEnabled(){
return true;
}
}
因为SysUser实体类继承UserDetails接口,这个类是基于Security的安全服务。所以通过继承UserDetails这个类,我们就可以实现Security中相关的功能了,后面我们会具体介绍是怎么一回事。
用户关系实体类:SysRole
package org.security.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class SysRole{
@Id
@GeneratedValue
private Long id;
private String name;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}SysRole实体类是保存着用户的拥有什么样权限的实体类。和用户实体是多对一的关系,也就是一个用户可以拥有多个权限。
实体类创建好之后,我们就可以编写相应的dao,service,controller类来实现用户登录的功能了。这里我会新建一个login.html页面和index.html页面,来进行登录校验的和权限控制演示。
dao接口(这里我采用jpa来实现用户查询的功能)
package org.security.dao;
import org.security.entity.SysUser;
import org.springframework.data.jpa.repository.JpaRepository;
public interface SysUserRepository extends JpaRepository{
SysUser findByUsername(String username);
}service业务类
package org.security.service;
import org.security.dao.SysUserRepository;
import org.security.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class CustomUserService implements UserDetailsService{
@Autowired
SysUserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException{
SysUser user = userRepository.findByUsername(s);
if (user == null) {
throw new UsernameNotFoundException("用户名不存在");
}
System.out.println("s:"+s);
System.out.println("username:"+user.getUsername()+";password:"+user.getPassword());
System.out.println("size:"+user.getRoles().size());
System.out.println("role:"+user.getRoles().get(0).getName());
return user;
}
}controller控制类:
package org.security.controller;
import org.security.entity.Msg;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created by linzhiqiang on 2017/10/26
*/
@Controller
public class HomeController{
@RequestMapping("/")
public String index(Model model){
Msg msg = new Msg("测试标题", "测试内容", "额外信息,只对管理员显示");
model.addAttribute("msg", msg);
return "index";
}
@PreAuthorize("hasAuthority('ROLE_USER')")
@RequestMapping(value="/admin/test1")
@ResponseBody
public String adminTest1(){
return "ROLE_USER";
}
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@RequestMapping("/admin/test2")
@ResponseBody
public String adminTest2(){
return "ROLE_ADMIN";
}
}login.html页面:
登录
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
Spring Security演示
- 首页
- 百度
已注销
有错误,请重试
使用账号密码登录
账号
密码
index.html页面:
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
Spring Security演示
- 首页
- 百度
无更多显示信息
4.SpringBoot中配置基于security的支持,这里我有两个配置
一个是没有登录用户都跳转到login.html页面的配置:
package org.security.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/login").setViewName("login");
}
}接下来就是security核心的配置类了:
package org.security.config;
import org.security.service.CustomUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
protected UserDetailsService customUserService(){
return new CustomUserService();
}
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
authenticationManagerBuilder
// 设置UserDetailsService
.userDetailsService(customUserService())
// 使用BCrypt进行密码的hash
.passwordEncoder(passwordEncoder());
}
// 装载BCrypt密码编码器
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception{
return new JwtAuthenticationTokenFilter();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(customUserService());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity
// 由于使用的是JWT,我们这里不需要csrf
// .csrf().disable()
// 基于token,所以不需要session
// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
//.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// 允许对于网站静态资源的无授权访问
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
// 对于获取token的rest api要允许匿名访问
.antMatchers("/auth/**").permitAll()
.antMatchers("/admin/**").hasIpAddress("127.0.0.1")
.antMatchers("/admin/**").access("hasAuthority('ROLE_ADMIN')")
.anyRequest().authenticated().and().formLogin().loginPage("/login")
.failureUrl("/login?error").permitAll().and().logout().permitAll();
// 除上面外的所有请求全部需要鉴权认证
//.anyRequest().authenticated();
// 添加JWT filter
// httpSecurity
// .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
// 禁用缓存
// httpSecurity.headers().cacheControl();
}
}这里我暂时先把jwt相关的代码先注释掉,将注解取消掉的话,就可以实现jwt相关的功能了。
5.打开浏览器进行功能测试,下面是测试的结果:
如果未登录的话,就都会跳转到这个login.html登录页面
登录成功后进入的index页面,这里测试的账户权限类型是admin,下面有两个地址一个是admin/test1只能user权限才可以访问,还有一个是admin/test2拥有admin权限的人才可以访问,下面我们开始测试。
因为权限不够所以,返回的是403错误。
权限够的话,返回的是这个接口获取的数据。
到这里关于SpringBoot整合Security就介绍完了,接下来就是如何添加jwt的支持了。6.基本过程和security差不多:
一:首先创建一个工具类,用来生成jwt的token和token的验证刷新之类的。
二:然后创建一个fiter类,并配置注入security配置文件中
三:接下来就是创建dao,service,controller来实现接口。
四:最后就是利用postman来测试是否实现jwt功能
工具类JwtTokenUtil:package org.security.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.security.entity.SysUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtTokenUtil implements Serializable{
private static final long serialVersionUID = -3301605591108950415L;
private static final String CLAIM_KEY_USERNAME = "sub";
private static final String CLAIM_KEY_CREATED = "created";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String getUsernameFromToken(String token){
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
public Date getCreatedDateFromToken(String token){
Date created;
try {
final Claims claims = getClaimsFromToken(token);
created = new Date((Long) claims.get(CLAIM_KEY_CREATED));
} catch (Exception e) {
created = null;
}
return created;
}
public Date getExpirationDateFromToken(String token){
Date expiration;
try {
final Claims claims = getClaimsFromToken(token);
expiration = claims.getExpiration();
} catch (Exception e) {
expiration = null;
}
return expiration;
}
private Claims getClaimsFromToken(String token){
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
private Date generateExpirationDate(){
return new Date(System.currentTimeMillis() + expiration * 1000);
}
private Boolean isTokenExpired(String token){
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset){
return (lastPasswordReset != null && created.before(lastPasswordReset));
}
public String generateToken(UserDetails userDetails){
Map claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
String generateToken(Map claims){
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset){
final Date created = getCreatedDateFromToken(token);
return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
&& !isTokenExpired(token);
}
public String refreshToken(String token){
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.put(CLAIM_KEY_CREATED, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
public Boolean validateToken(String token, UserDetails userDetails){
SysUser user = (SysUser) userDetails;
final String username = getUsernameFromToken(token);
final Date created = getCreatedDateFromToken(token);
// final Date expiration = getExpirationDateFromToken(token);
return (
username.equals(user.getUsername())
&& !isTokenExpired(token)
&& !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()));
}
}dao接口:package org.security.dao;
import org.security.entity.SysUser;
public interface AuthService{
SysUser register(SysUser userToAdd);
String login(String username, String password);
String refresh(String oldToken);
}dao接口实现类(service业务类):package org.security.service;
import org.security.dao.AuthService;
import org.security.dao.SysUserRepository;
import org.security.entity.SysUser;
import org.security.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Date;
import static java.util.Arrays.asList;
@Service
public class AuthServiceImpl implements AuthService{
private AuthenticationManager authenticationManager;
private UserDetailsService userDetailsService;
private JwtTokenUtil jwtTokenUtil;
private SysUserRepository userRepository;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
public AuthServiceImpl(
AuthenticationManager authenticationManager,
UserDetailsService userDetailsService,
JwtTokenUtil jwtTokenUtil,
SysUserRepository userRepository) {
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.jwtTokenUtil = jwtTokenUtil;
this.userRepository = userRepository;
}
@Override
public SysUser register(SysUser userToAdd){
final String username = userToAdd.getUsername();
if(userRepository.findByUsername(username)!=null) {
return null;
}
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
final String rawPassword = userToAdd.getPassword();
userToAdd.setPassword(encoder.encode(rawPassword));
userToAdd.setLastPasswordResetDate(new Date());
// userToAdd.setRoles(asList("ROLE_USER"));
return userRepository.save(userToAdd);
}
@Override
public String login(String username, String password){
UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
// Perform the security
final Authentication authentication = authenticationManager.authenticate(upToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
// Reload password post-security so we can generate token
final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
final String token = jwtTokenUtil.generateToken(userDetails);
return token;
}
@Override
public String refresh(String oldToken){
final String token = oldToken.substring(tokenHead.length());
String username = jwtTokenUtil.getUsernameFromToken(token);
SysUser user = (SysUser) userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())){
return jwtTokenUtil.refreshToken(token);
}
return null;
}
}controller控制类:
package org.security.controller;
import org.security.dao.AuthService;
import org.security.entity.SysUser;
import org.security.service.JwtAuthenticationRequest;
import org.security.service.JwtAuthenticationResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class AuthController{
@Value("${jwt.header}")
private String tokenHeader;
@Autowired
private AuthService authService;
@RequestMapping(value = "/auth/login", method = RequestMethod.POST)
public ResponseEntity> createAuthenticationToken(
String username,String password
) throws AuthenticationException{
// @RequestBody JwtAuthenticationRequest authenticationRequest
final String token = authService.login(username,password);
// Return the token
return ResponseEntity.ok(new JwtAuthenticationResponse(token));
}
@RequestMapping(value = "/auth/refresh", method = RequestMethod.GET)
public ResponseEntity> refreshAndGetAuthenticationToken(
HttpServletRequest request) throws AuthenticationException{
String token = request.getHeader(tokenHeader);
String refreshedToken = authService.refresh(token);
if(refreshedToken == null) {
return ResponseEntity.badRequest().body(null);
} else {
return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken));
}
}
@RequestMapping(value = "${jwt.route.authentication.register}", method = RequestMethod.POST)
public SysUser register(@RequestBody SysUser addedUser) throws AuthenticationException{
return authService.register(addedUser);
}
}
接在来就是最重要的filter类:
package org.security.config;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.security.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter{
@Autowired
private UserDetailsService userDetailsService;
@Value("${jwt.header}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String authHeader = request.getHeader(this.tokenHeader);
if (authHeader != null && authHeader.startsWith(tokenHead)) {
final String authToken = authHeader.substring(tokenHead.length()); // The part after "Bearer "
String username = jwtTokenUtil.getUsernameFromToken(authToken);
logger.info("checking authentication " + username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(
request));
logger.info("authenticated user " + username + ", setting security context");
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}将security中配置文件注解去掉,去掉之后如下所示:
package org.security.config;
import org.security.service.CustomUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
protected UserDetailsService customUserService(){
return new CustomUserService();
}
@Autowired
public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
authenticationManagerBuilder
// 设置UserDetailsService
.userDetailsService(customUserService())
// 使用BCrypt进行密码的hash
.passwordEncoder(passwordEncoder());
}
// 装载BCrypt密码编码器
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception{
return new JwtAuthenticationTokenFilter();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(customUserService());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity
// 由于使用的是JWT,我们这里不需要csrf
.csrf().disable()
// 基于token,所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// 允许对于网站静态资源的无授权访问
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
// 对于获取token的rest api要允许匿名访问
.antMatchers("/auth/**").permitAll()
.antMatchers("/admin/**").hasIpAddress("127.0.0.1")
.antMatchers("/admin/**").access("hasAuthority('ROLE_ADMIN')")
// .anyRequest().authenticated().and().formLogin().loginPage("/login")
// .failureUrl("/login?error").permitAll().and().logout().permitAll();
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
// 添加JWT filter
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
// 禁用缓存
httpSecurity.headers().cacheControl();
}
}到这边jwt整合也介绍了,现在我们就可以postman来进行测试。
测试结果如下所示:
生成token:
刷新token:
不带token访问接口:
带token但是权限不够:
带token而且权限也够:
到这里关于 SpringBoot+SpringSecurity+JWT就基本结束了,这篇博客我重点是将如何通过代码来实现这个功能,关于代码本身没有很细致的介绍。关于代码功能的介绍,例如怎么通过注解配置权限控制,如何通过配置来进行权限控制,token更新和验证等等的细节,我会在我这篇博客的教学视频中介绍,视频地址:
GitHub地址
如果大家对文章有什么问题或者疑意之类的,可以加我订阅号在上面留言,订阅号上面我会定期更新最新博客。如果嫌麻烦可以直接加我wechat:lzqcode
html jwt权限控制,SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制相关推荐
- Java权限管理|基于springBoot+springSecurity+jwt实现前后端分离用户权限认证
基于springBoot+springSecurity+jwt实现前后端分离用户权限认证 1. 项目说明 主要基于前后端分离情况下用户权限认证, 当用户登录认证成功后,每个用户会获取到自己的tok ...
- Springboot+Spring-Security+JWT 实现用户登录和权限认证
如今,互联网项目对于安全的要求越来越严格,这就是对后端开发提出了更多的要求,目前比较成熟的几种大家比较熟悉的模式,像RBAC 基于角色权限的验证,shiro框架专门用于处理权限方面的,另一个比较流行的 ...
- SpringBoot+SpringSecurity+JWT实现认证和授权
SprinBoot 系列文章: Spring Boot入门之Hello Spring Boot SpringBoot 配置多个JdbcTemplate SpringBoot 整合Mybatis CAS ...
- JWT 教程_1 SpringBoot与JWT整合
https://gitee.com/fakerlove/spring-security 文章目录 1. 介绍 2. SpringBoot与JWT整合 2.1 JWT的结构: 2.2 JWT的使用测试: ...
- 权限管理SpringBoot+SpringSecurity系列文章 - 导读
课程介绍 Spring Security是一个基于Spring的安全框架,提供了一套Web应用安全性的完整解决方案.一般来说,Web应用的安全性包括用户认证(Authentication)和用户授权( ...
- SpringBoot+SpringSecurity+JWT整合实现单点登录SSO史上最全详解
作者:波波烤鸭 blog.csdn.net/qq_38526573/article/details/103409430 一.什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是 ...
- SpringtBoot+SpringSecurity+Jwt+MyBatis整合实现用户认证以及权限控制
文章目录 前言 数据库表结构 项目结构图 核心配置类SecurityConfig 实体类 工具类 用户登录认证 Token令牌验证 获取用户权限 用户权限验证 Service层实现类 统一响应类 Co ...
- springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)
用户实体类 参考:springboot+springsecurity基于角色的权限验证(二) 配置类 @Configuration @EnableWebSecurity @EnableGlobalMe ...
- Springboot集成JWT做认证授权
目录 1.1.JWT简介 1.2.JWT能做什么? 1.3.JWT认证流程是什么? 1.4.JWT的结构是什么? 1.5.使用JWT 1.生成token 2.解析token 1.6.封装工具类 1.7 ...
最新文章
- java的byte php_java_浅谈java的byte数组的不同写法,(由于篇幅原因阐述的不够详 - phpStudy...
- java 四种实现延迟加载的方法
- Ambari中Ranger安装
- 解题报告——蓝桥杯 试题 基础练习 字符串对比——16行代码AC
- CodeForces616:Educational Round 5
- 解三对角线性方程组的追赶法
- C++实现 逆波兰表达式计算问题
- linux虚拟机上挂载U盘
- 量子场论考试必会题目
- HR问:“你为什么离开上一家公司?”,这样回答最机智
- Jetson Nano 从入门到实战(转载)(案例:Opencv配置、人脸检测、二维码检测)
- 低碳环保+变废为宝=马铃薯淀粉生产废水处理设备
- HTML文本抖音李峋同款爱心代码超好看
- 区块链入门教程(7)--使用控制台部署及调用合约
- const定义及初始化约束
- 秋招面经汇总(算法工程师,计算机视觉工程师,深度学习工程师,机器学习工程师)
- Java 变量作用域、构造方法官方教程
- DE2带的IP核ISP12362报错问题解决 Error:avalon_slave_1_irq: associatedAddressablePoint out of range...
- html vw选择器,使用vw、vh的使用教程
- horizon层层注册
热门文章
- mysql 字段加减_MySQL数据库开发常见问题及优化(续)
- 开课吧里的python学习是真的吗-Python是个什么鬼?为何学英语的都在关注...
- python全套完整教程-Python语言基础50课 全套完整版(含doc版)
- python编程100个小程序-整理了适合新手的20个Python练手小程序
- python是什么类型的语言-编程语言分类及python所属类型
- python基础教程书籍-Python基础教程(第2版)
- JwtUtil-MD5Util-RedisUtil,以及springboot aop练习(记录)
- android 4实例分析,OpenGL Shader实例分析(4)闪光效果
- android alphaanimation xml,android AlphaAnimation动画代码实现与XML实现
- java开发 网关_SpringCloud系列之网关(Gateway)应用篇