新增jwt增强
This commit is contained in:
parent
85a6e2a486
commit
c77960c777
@ -0,0 +1,10 @@
|
|||||||
|
package cn.zyjblogs.common.entity.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhuyijun
|
||||||
|
*/
|
||||||
|
public class ContextKeyConstant {
|
||||||
|
public static final String USER_ID_KEY = "user_id";
|
||||||
|
public static final String USERNAME_KEY = "username";
|
||||||
|
public static final String TENANT_ID_KEY = "tenant_id";
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.zyjblogs.common.entity.jwt;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.impl.DefaultClaims;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhuyijun
|
||||||
|
*/
|
||||||
|
public class OauthClaims extends DefaultClaims {
|
||||||
|
|
||||||
|
public String getUserId(){
|
||||||
|
return this.getString("user_id");
|
||||||
|
}
|
||||||
|
public void setUserId(String userId){
|
||||||
|
this.setValue("user_id",userId);
|
||||||
|
}
|
||||||
|
public String getUsername(){
|
||||||
|
return this.getString("username");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username){
|
||||||
|
this.setValue("username", username);
|
||||||
|
}
|
||||||
|
}
|
@ -86,10 +86,10 @@
|
|||||||
<!-- <groupId>org.springframework.security.oauth.boot</groupId>-->
|
<!-- <groupId>org.springframework.security.oauth.boot</groupId>-->
|
||||||
<!-- <artifactId>spring-security-oauth2-autoconfigure</artifactId>-->
|
<!-- <artifactId>spring-security-oauth2-autoconfigure</artifactId>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<!-- <groupId>org.springframework.cloud</groupId>-->
|
||||||
<artifactId>spring-cloud-starter-oauth2</artifactId>
|
<!-- <artifactId>spring-cloud-starter-oauth2</artifactId>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.zyjblogs.starter</groupId>
|
<groupId>cn.zyjblogs.starter</groupId>
|
||||||
<artifactId>zyjblogs-common-spring-boot-starter</artifactId>
|
<artifactId>zyjblogs-common-spring-boot-starter</artifactId>
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
package cn.zyjblogs.gateway.filter;
|
package cn.zyjblogs.gateway.filter;
|
||||||
|
|
||||||
import cn.zyjblogs.common.entity.constant.HttpHeaderConstant;
|
import cn.zyjblogs.common.entity.constant.HttpHeaderConstant;
|
||||||
|
import cn.zyjblogs.common.entity.context.BaseContextHandler;
|
||||||
|
import cn.zyjblogs.common.entity.dto.ContextDto;
|
||||||
|
import cn.zyjblogs.common.entity.jwt.OauthClaims;
|
||||||
import cn.zyjblogs.common.entity.response.ResponseObject;
|
import cn.zyjblogs.common.entity.response.ResponseObject;
|
||||||
import cn.zyjblogs.common.entity.response.ResponseResult;
|
import cn.zyjblogs.common.entity.response.ResponseResult;
|
||||||
import cn.zyjblogs.common.entity.response.ResponseStatus;
|
import cn.zyjblogs.common.entity.response.ResponseStatus;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwt;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
@ -43,7 +49,7 @@ import java.util.List;
|
|||||||
public class AuthFilter implements GlobalFilter {
|
public class AuthFilter implements GlobalFilter {
|
||||||
private final WhiteListProperties whiteListProperties;
|
private final WhiteListProperties whiteListProperties;
|
||||||
private AntPathMatcher antPathMatcher = new AntPathMatcher();
|
private AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||||
|
private String SIGNING_KEY="zyjblogs123";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
@ -98,6 +104,8 @@ public class AuthFilter implements GlobalFilter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String jwt = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE + " ", "");
|
String jwt = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE + " ", "");
|
||||||
|
OauthClaims body = (OauthClaims) Jwts.parser().setSigningKey(SIGNING_KEY).parseClaimsJws(jwt).getBody();
|
||||||
|
BaseContextHandler.set(ContextDto.builder().token(jwt).userId(body.getUserId()).username(body.getUsername()).build());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,12 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.zyjblogs.starter</groupId>
|
||||||
|
<artifactId>zyjblogs-common-spring-boot-starter</artifactId>
|
||||||
|
<version>${zyjblogs.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -44,6 +44,7 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
|
|||||||
private final JwtAccessTokenConverter accessTokenConverter;
|
private final JwtAccessTokenConverter accessTokenConverter;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
|
private final JwtTokenEnhancer jwtTokenEnhancer;
|
||||||
/**
|
/**
|
||||||
* 令牌端点的安全约束
|
* 令牌端点的安全约束
|
||||||
*
|
*
|
||||||
@ -56,7 +57,7 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
|
|||||||
security
|
security
|
||||||
//允许匿名访问端点:url:/oauth/token_key
|
//允许匿名访问端点:url:/oauth/token_key
|
||||||
.tokenKeyAccess("permitAll()")
|
.tokenKeyAccess("permitAll()")
|
||||||
.checkTokenAccess("permitAll()")
|
.checkTokenAccess("isAuthenticated()")
|
||||||
//TODO 待处理令牌访问安全
|
//TODO 待处理令牌访问安全
|
||||||
//允许匿名访问端点:url:/oauth/check_token
|
//允许匿名访问端点:url:/oauth/check_token
|
||||||
// .checkTokenAccess("isAuthenticated()")
|
// .checkTokenAccess("isAuthenticated()")
|
||||||
@ -83,12 +84,14 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||||
|
|
||||||
endpoints.
|
endpoints.
|
||||||
//密码模式
|
//密码模式
|
||||||
authenticationManager(authenticationManager)
|
authenticationManager(authenticationManager)
|
||||||
//授权码模式
|
//授权码模式
|
||||||
.authorizationCodeServices(authorizationCodeServices(dataSource))
|
.authorizationCodeServices(authorizationCodeServices(dataSource))
|
||||||
.tokenServices(tokenServices())
|
.tokenServices(tokenServices())
|
||||||
|
.accessTokenConverter(accessTokenConverter)
|
||||||
//允许表单认证
|
//允许表单认证
|
||||||
.allowedTokenEndpointRequestMethods(HttpMethod.POST);
|
.allowedTokenEndpointRequestMethods(HttpMethod.POST);
|
||||||
}
|
}
|
||||||
@ -107,8 +110,9 @@ public class AuthorizationServerConfiguration extends AuthorizationServerConfigu
|
|||||||
tokenServices.setSupportRefreshToken(true);
|
tokenServices.setSupportRefreshToken(true);
|
||||||
//令牌储存策略
|
//令牌储存策略
|
||||||
tokenServices.setTokenStore(tokenStore);
|
tokenServices.setTokenStore(tokenStore);
|
||||||
tokenServices.setTokenEnhancer(accessTokenConverter);
|
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
|
||||||
|
enhancerChain.setTokenEnhancers(List.of(jwtTokenEnhancer,accessTokenConverter));
|
||||||
|
tokenServices.setTokenEnhancer(enhancerChain);
|
||||||
//令牌默认有效期
|
//令牌默认有效期
|
||||||
tokenServices.setAccessTokenValiditySeconds(7200);
|
tokenServices.setAccessTokenValiditySeconds(7200);
|
||||||
//刷新令牌默认有效期3天
|
//刷新令牌默认有效期3天
|
||||||
|
@ -11,7 +11,7 @@ import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
|||||||
* @author zhuyijun
|
* @author zhuyijun
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class TokenConfig {
|
public class JwtTokenConfig {
|
||||||
private String SIGNING_KEY="zyjblogs123";
|
private String SIGNING_KEY="zyjblogs123";
|
||||||
/**
|
/**
|
||||||
* 令牌存储策略
|
* 令牌存储策略
|
@ -0,0 +1,39 @@
|
|||||||
|
package cn.zyjblogs.oauth.config.security;
|
||||||
|
|
||||||
|
import cn.zyjblogs.common.entity.constant.ContextKeyConstant;
|
||||||
|
import cn.zyjblogs.oauth.server.user.po.OauthUserDetails;
|
||||||
|
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||||
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
|
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||||
|
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt内容增强器
|
||||||
|
* @author zhuyijun
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class JwtTokenEnhancer implements TokenEnhancer {
|
||||||
|
/**
|
||||||
|
* token增强
|
||||||
|
* @param oAuth2AccessToken
|
||||||
|
* @param authentication
|
||||||
|
* @author zhuyijun
|
||||||
|
* @date 2022/8/18 下午8:51
|
||||||
|
* @return org.springframework.security.oauth2.common.OAuth2AccessToken
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication authentication) {
|
||||||
|
OauthUserDetails authUser = (OauthUserDetails) authentication.getPrincipal();
|
||||||
|
final Map<String, Object> additionalInfo = new HashMap<>(4);
|
||||||
|
// 注意添加的额外信息,不能和已有的json对象中的key重名
|
||||||
|
additionalInfo.put(ContextKeyConstant.USER_ID_KEY, authUser.getId());
|
||||||
|
additionalInfo.put(ContextKeyConstant.USERNAME_KEY, authUser.getUsername());
|
||||||
|
((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionalInfo);
|
||||||
|
return oAuth2AccessToken;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package cn.zyjblogs.oauth.config.security;
|
||||||
|
|
||||||
|
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.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhuyijun
|
||||||
|
*/
|
||||||
|
//@Component("oauthAuthenticationProvider")
|
||||||
|
//public class OauthAuthenticationProvider extends DaoAuthenticationProvider {
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
|
||||||
|
// super.additionalAuthenticationChecks(userDetails, authentication);
|
||||||
|
// }
|
||||||
|
//}
|
@ -1,8 +1,11 @@
|
|||||||
package cn.zyjblogs.oauth.config.security;
|
package cn.zyjblogs.oauth.config.security;
|
||||||
|
|
||||||
|
import cn.zyjblogs.oauth.server.user.service.impl.OauthUserDetailsServiceImpl;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
@ -19,8 +22,11 @@ import javax.sql.DataSource;
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
// private final OauthUserDetailsServiceImpl oauthUserDetailsService;
|
||||||
|
// private final OauthAuthenticationProvider oauthAuthenticationProvider;
|
||||||
/**
|
/**
|
||||||
* 密码编码解码
|
* 密码编码解码
|
||||||
*
|
*
|
||||||
@ -44,6 +50,13 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
return super.authenticationManagerBean();
|
return super.authenticationManagerBean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
// auth.authenticationProvider(oauthAuthenticationProvider)
|
||||||
|
// .userDetailsService(oauthUserDetailsService)
|
||||||
|
// .passwordEncoder(passwordEncoder());
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http.csrf().disable();
|
http.csrf().disable();
|
||||||
|
@ -11,6 +11,7 @@ import lombok.Setter;
|
|||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ import java.util.Set;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public class OauthUserDetails implements UserDetails {
|
public class OauthUserDetails implements UserDetails, Serializable {
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
@ -44,6 +45,91 @@ public class OauthUserDetails implements UserDetails {
|
|||||||
private boolean accountNonLocked = true;
|
private boolean accountNonLocked = true;
|
||||||
private boolean credentialsNonExpired = true;
|
private boolean credentialsNonExpired = true;
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(Integer phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInviteUserId() {
|
||||||
|
return inviteUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInviteUserId(String inviteUserId) {
|
||||||
|
this.inviteUserId = inviteUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Integer status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(Integer deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthorities(Collection<GrantedAuthority> authorities) {
|
||||||
|
this.authorities = authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountNonExpired(boolean accountNonExpired) {
|
||||||
|
this.accountNonExpired = accountNonExpired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountNonLocked(boolean accountNonLocked) {
|
||||||
|
this.accountNonLocked = accountNonLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
|
||||||
|
this.credentialsNonExpired = credentialsNonExpired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
return authorities;
|
return authorities;
|
||||||
|
@ -15,7 +15,10 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
/**
|
||||||
|
* @author zhuyijun
|
||||||
|
*/
|
||||||
|
@Service("oauthUserDetailsService")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OauthUserDetailsServiceImpl implements UserDetailsService {
|
public class OauthUserDetailsServiceImpl implements UserDetailsService {
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
Loading…
Reference in New Issue
Block a user