gpt4 book ai didi

java - 我可以在没有用户的情况下为我的 Spring Security 应用程序生成 JWT 吗?

转载 作者:行者123 更新时间:2023-12-02 09:23:07 26 4
gpt4 key购买 nike

我想生成一个带有到期日期的 JWT,以便人们无需注册和创建用户即可访问系统。这可能吗?我尝试过使用JwtTokenProvider,但它需要LoginRequest才能工作,而且Jwts.builder()也需要用户。

最佳答案

if you want to use spring security you can create security configration and extends WebSecurityConfigurerAdapter. Then important point is custom provider.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;

@Autowired
private JWTConfigurer securityConfigurerAdapter;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//you can write customAuth provider
auth.authenticationProvider(customAuthenticationProvider);
}


@Override
public void configure(WebSecurity web) throws Exception {
//Some ignore etc.

}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.csrf()
.disable().and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
//important here
.antMatchers("/api/v1/authentication/**").permitAll()
.anyRequest().authenticated()
.and()
.apply(securityConfigurerAdapter);
}


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

}

This is Filter class which extends genericFilterBean. Every request is monitored in this class You will check to it is right token

I create token TokenProvider class and depend into JWTFilter then use valideToken method.

if token is sended and not validate then throw exception

if token is not sended then go super method so the flow is continue and works auth.authenticationProvider. Spring knows to start customAuthenticationProvider behind the scene becouse of you set into SecurityConfiguration class

@Component
public class JWTFilter extends GenericFilterBean {

private final Logger log = LoggerFactory.getLogger(JWTFilter.class);

@Autowired
private TokenProvider tokenProvider;

@Autowired
private MessageSource msgSource;

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

//Resolve method is optional what you want to use
String jwt = resolveToken(httpServletRequest);
if (StringUtils.hasText(jwt)) {
//token validation is important becouse of expires date into token
// and you will check expired date
if (this.tokenProvider.validateToken(jwt)) {
String jwtMd5 = DigestUtils.md5Hex(jwt);
MDC.put("jwt",jwtMd5);
Authentication authentication = this.tokenProvider.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(servletRequest, servletResponse);
}catch(Exception ex){
handleException((HttpServletResponse) servletResponse,ex);
}
}

private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(JWTConfigurer.AUTHENTICATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
String jwt = bearerToken.substring(7, bearerToken.length());
return jwt;
}

String jwt = request.getParameter(JWTConfigurer.AUTHENTICATION_TOKEN);
if (StringUtils.hasText(jwt)) {
return jwt;
}
return null;
}


}

You can use this class for create token or validate token you define expire date for token expiration into create method.

@Component public class TokenProvider {

private final Logger log = LoggerFactory.getLogger(TokenProvider.class);

private static final String AUTHORITIES_KEY = "auth";
private static final String WTS_USER_ID = "wtsUserId";
private static final String CHANNEL_PERMISSIONS = "channelPermissions";
private static final String APP_ROLES = "appRoles";

private String secretKey;

private long tokenValidityInSeconds;

@Autowired private ApplicationProperties applicationProperties;

@PostConstruct public void init() {

this.tokenValidityInSeconds = 1000;
}

public String createToken(Authentication authentication, Boolean rememberMe) { List<String> authorities = authentication.getAuthorities().stream().map(authority -> authority.getAuthority())
.collect(Collectors.toList());

//Token creation format is this
// token will be three part important parts are claims and sign
// claims refers to body to use datas
// sign will use to validation
return Jwts.builder().setSubject(authentication.getName()).claim(AUTHORITIES_KEY, authorities)
.claim(WTS_USER_ID, ((JWTAuthentication) authentication).getWtsUserId())
.claim(CHANNEL_PERMISSIONS, ((JWTAuthentication) authentication).getChannelPermissions())
.claim(APP_ROLES, ((JWTAuthentication) authentication).getAppRoles())
.signWith(SignatureAlgorithm.HS512, secretKey).setExpiration(tokenValidityInSeconds).compact(); }

@SuppressWarnings("unchecked") public Authentication getAuthentication(String token) { Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();


List<String> list = (List<String>) claims.get(AUTHORITIES_KEY); Collection<? extends GrantedAuthority> authorities = list.stream()
.map(authority -> new SimpleGrantedAuthority(authority)).collect(Collectors.toList()); Integer wtsUserId = (Integer) claims.get(WTS_USER_ID); List<String> appRoles = (List<String>) claims.get(APP_ROLES);

ObjectMapper objectMapper = new ObjectMapper(); List<ChannelPermission> channelPermissions = objectMapper.convertValue(claims.get(CHANNEL_PERMISSIONS),
new TypeReference<List<ChannelPermission>>() {
});

return new JWTAuthentication(token, wtsUserId, claims.getSubject(), authorities, channelPermissions, appRoles); }

public boolean validateToken(String authToken) {
try {

Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
return true;

} catch (SignatureException e) {
log.info("Invalid JWT signature: " + e.getMessage());
return false;
} } }

This is controller who anonymous people get a JWT token .You can give a new JWT token all request and this JWT has expires date becouse of you set a expiration date into provider class.

@RequestMapping(value = "/login", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ApiResponse login(@RequestBody @Validated AuthenticationRequestDTO authenticationRequest) {

Authentication authentication = this.authenticationManager.authenticate(new JWTAuthentication(
RandomUid, RandomPwd, "anonymous"));
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = tokenProvider.createToken(authentication, false);
return new ApiResponse(ApiResponseStatus.SUCCESS, new AuthenticationResponseDTO(token));
}

关于java - 我可以在没有用户的情况下为我的 Spring Security 应用程序生成 JWT 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58529775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com