在自定义过滤器中,请求中的用户名和密码显示为空。通过浏览器:http://username:password@localhost:8090/login我假设这将调用Spring Security的默认登录。在自定义过滤器中,请求中的用户名和密码显示为null,即使我给予了正确的用户名和密码。因此凭据失败。因此返回403。自定义过滤器是否未注册或未获得请求。任何帮助。提前感谢。
WebSecurityConfig.java 文件:
//WebSecurityConfig.java file
package com.example.demo.configuration;
import java.util.Arrays;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.example.demo.services.AuthenticationProviderService;
import com.example.demo.filters.DtscCustomUsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private DtscCustomUsernamePasswordAuthenticationFilter dtscCustomerUsernamePasswordAutenticationFilter;
@Autowired
private AuthenticationProviderService authenticationProvider;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.cors().and().authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/").permitAll().anyRequest()
.authenticated();
http.addFilterAt(dtscCustomerUsernamePasswordAutenticationFilter, BasicAuthenticationFilter.class);
}
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
DtscCustomUsernamePasswordAuthenticationFilter:
//DtscCustomUsernamePasswordAuthenticationFilter.java file
package com.example.demo.filters;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class DtscCustomUsernamePasswordAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private AuthenticationManager authenticationManager;
@Value("${jwt.signing.key}")
private String signingKey;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String username = null;
String password = null;
System.out.println(request);
try{
username = request.getParameter("username");
password = request.getParameter("password");
System.out.println(username);
System.out.println(password);
}
catch(Exception e) {
throw new AuthenticationServiceException(e.getMessage(), e);
}
Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password);
authenticationManager.authenticate(authRequest);
SecretKey key = Keys.hmacShaKeyFor(signingKey.getBytes(StandardCharsets.UTF_8));
HashMap<String, Object> claims = new HashMap<>();
claims.put("username", username);
String jwt = Jwts.builder()
.setClaims(claims)
.signWith(key)
.compact();
response.setHeader("Authorization", jwt);
chain.doFilter(request, response);
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return !request.getServletPath().equals("/login"); }
}
AuthenticationProviderService:
//AuthenticationProviderService .java file
package com.example.demo.services;
import com.example.demo.respository.DtscUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
@Service
public class AuthenticationProviderService implements AuthenticationProvider{
@Autowired
private DtscUserDetailsService dtscUserDetailsService;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = String.valueOf(authentication.getCredentials());
DtscUserDetails user = dtscUserDetailsService.loadUserByUsername(username);
return checkPassword(user, password, bCryptPasswordEncoder);
}
@Override
public boolean supports(Class<?> aClass) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
}
private Authentication checkPassword(DtscUserDetails user, String rawPassword, PasswordEncoder encoder) {
if (encoder.matches(rawPassword, user.getPassword())) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
} else {
throw new BadCredentialsException("Bad credentials");
}
}
}
DtscUserDetailsService:
//DtscUserDetailsService.java file
package com.example.demo.services;
import com.example.demo.entities.DtscUser;
import com.example.demo.respository.DtscUserDetails;
import com.example.demo.respository.DtscUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.function.Supplier;
@Service
public class DtscUserDetailsService implements UserDetailsService{
@Autowired
private DtscUserRepository dtscUserRepository;
@Override
public DtscUserDetails loadUserByUsername(String username) {
Supplier<UsernameNotFoundException> s = () -> new UsernameNotFoundException("Bad Credentials!");
DtscUser u = dtscUserRepository.findDtscUserByUsername(username).orElseThrow(s);
return new DtscUserDetails(u);
}
}
DtscUserDetails:
//DtscUserDetails.java file
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.stream.Collectors;
public class DtscUserDetails implements UserDetails {
private final DtscUser dtscUser;
public DtscUserDetails(DtscUser dtscUser) {
this.dtscUser = dtscUser;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return dtscUser.getListOfDtscAuthority().stream()
.map(a -> new SimpleGrantedAuthority(a.getUsername()))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return dtscUser.getPassword();
}
@Override
public String getUsername() {
return dtscUser.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public final DtscUser getUser() {
return dtscUser;
}
}
1条答案
按热度按时间ds97pgxw1#
request.getParameter("username")
将从querystring参数中提取username,而不是从给定的URLhttp://username:password@localhost:8090/login
中提取。**注意:**在URL中发送用户名和密码是安全流程,不推荐使用。始终使用POST请求,请求体中发送usename/password。