Я работаю над приложением SpringBoot 2.0 с Spring Web, Spring Security и использую JWT для аутентификации.Существует только один путь URI, который является общедоступным и доступен любому, за исключением того, что все другие URI защищены и выдают «Отказано в доступе» во время любой попытки.Я могу получить доступ к этому общедоступному URI и создать нового пользователя в базе данных с именем пользователя и паролем.Однако, когда я пытаюсь войти с теми же учетными данными, я получаю HTTP 403 Forbidden error.
Пожалуйста, помогите мне здесь.Спасибо
Класс аутентификации: -
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private static Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
private AuthenticationManager authenticationManager;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
logger.info("Entering attemptAuthentication@JWTAuthenticationFilter");
try{
ApplicationUser credential = new ObjectMapper()
.readValue(request.getInputStream(), ApplicationUser.class);
logger.info("Validating Credential:: {}, {}", credential.getUsername(), credential.getPassword());
return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(credential.getUsername(),
credential.getPassword(), new ArrayList<>()));
}catch(IOException io){
throw new RuntimeException(io);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain, Authentication authResult)
throws IOException, ServletException {
logger.info("Entering successfulAuthentication@JWTAuthenticationFilter");
String jwtToken = Jwts.builder()
.setSubject(((User) authResult.getPrincipal()).getUsername())
.setExpiration(new Date(System.currentTimeMillis() + SecurityConstant.EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SecurityConstant.SECRET)
.compact();
logger.info("JWT Token:: {}", jwtToken);
response.addHeader(SecurityConstant.HEADER_STRING, SecurityConstant.TOKEN_PREFIX + jwtToken);
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
logger.info("Failed authentication while attempting to access");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
}
}
Класс авторизации: -
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
private static Logger logger = LoggerFactory.getLogger(JWTAuthorizationFilter.class);
public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
/**
*
* @param request
* @param response
* @param chain
* @throws IOException
* @throws ServletException
*/
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
logger.info("Entering doFilterInternal@JWTAuthorizationFilter");
String header = request.getHeader(SecurityConstant.HEADER_STRING);
logger.info("header:: {}", header);
if(null == header || !header.startsWith(SecurityConstant.TOKEN_PREFIX)){
logger.info("chaining");
chain.doFilter(request, response);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(header);
logger.info("Authentication:: {}", authentication);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
/**
*
* @param header
* @return
*/
private UsernamePasswordAuthenticationToken getAuthentication(String header){
logger.info("Entering getAuthenticationToken@JWTAuthorizationFilter");
logger.info("token::{}", header);
if(null != header){
//Parsing JWT Token
String user = Jwts.parser()
.setSigningKey(SecurityConstant.SECRET)
.parseClaimsJws(header.replace(SecurityConstant.TOKEN_PREFIX, ""))
.getBody()
.getSubject();
logger.info("user:: {}",user);
if(null != user){
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
Класс WebSecurity: -
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService,
BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf()
.disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, SecurityConstant.SIGN_UP_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
Файл Application.properties: -
#spring.security.user.name=user
#spring.security.user.password=user
spring.data.mongodb.uri=mongodb://localhost:27017/myspringdb
Тестовые данные PostMan для регистрации (работает): -
http://localhost:8080/users/sign-up
{
"id":"2",
"username":"user",
"password":"user",
"emailAddress":"abc@sample.com"
}
Данные теста PostMan для входа (не работает): -
http://localhost:8080/login
Заголовок: content-type: application / json
{
"username":"user",
"password":"user"
}
А также хочет знать, правильно ли я здесь делаю, не используя spring-security, потому что во время работы программы программа генерирует парольСамо по себе, как показано ниже: -
Использование сгенерированного пароля безопасности: ki908a3f-00ec-98cc-bn02-823ead10f153
Должен ли я использовать свои собственные учетные данные, сохраненные в базе данных (mongodb) или этой весной сгенерированный пароль для аутентификации?
Спасибо