【发布时间】:2019-01-31 14:34:49
【问题描述】:
我正在尝试掌握 Spring Security 和 经过相当多的工作(以及对 SO 的帮助),我能够在 Spring Security 中实现一些自定义身份验证机制,但现在我遇到了一些我不太了解的授权问题。
如果我向 localhost:8080/login?username=admin&password=sesamOeffneDich&secondSecret=youNeedMe 发出 POST 请求,我会收到 403 access denied.
如果有人能解释原因,我将不胜感激。
我的配置如下:
@Configuration
@EnableWebSecurity
@EnableWebMvc
@ComponentScan
public class AppConfig extends WebSecurityConfigurerAdapter
{
@Autowired
MyAuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.addFilterBefore(new MyAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class)
.authorizeRequests().antMatchers("/**")
.hasAnyRole()
.anyRequest()
.authenticated()
.and()
.csrf().disable()
.httpBasic().disable();
}
@Bean
public AuthenticationManager authenticationManager(){
return new ProviderManager(Arrays.asList(myAuthenticationProvider));
}
@Bean
public ViewResolver viewResolver()
{
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
我认为使用这种配置,授权机制会自动授予访问权限,原因是 [...].hasAnyRole()[...]。
这是我的令牌实现;为了练习目的,我想保持简单;如果需要理解实现的任何其他部分,请告诉我,我会提供它,但我不想一开始用不必要的代码过多地淹没帖子:
public class MyAuthenticationToken implements Authentication {
public static final String SECOND_SECRET = "youNeedMe";
private final String principalName;
private MyCredentials credentials;
private boolean authenticated;
public MyAuthenticationToken(String principalName, MyCredentials credentials) {
this.principalName = principalName;
this.credentials = credentials;
}
//Everyone is admin for the sake of the example
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
LinkedList<GrantedAuthority> authorities = new LinkedList<>();
authorities.add(new SimpleGrantedAuthority("ADMIN"));
return authorities;
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return this.principalName;
}
@Override
public boolean isAuthenticated() {
return this.authenticated;
}
@Override
public void setAuthenticated(boolean b) throws IllegalArgumentException {
this.authenticated = b;
}
@Override
public String getName() {
return this.principalName;
}
}
编辑:应要求我添加更多来源。
public class MyAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public MyAuthenticationFilter(AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher("/login", "POST"));
this.setAuthenticationManager(authenticationManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
String username = request.getParameter("username");
String password = request.getParameter("password");
String secondSecret = request.getParameter("secondSecret");
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
MyAuthenticationToken authRequest = new MyAuthenticationToken(username, new MyCredentials(password, secondSecret));
return this.getAuthenticationManager().authenticate(authRequest);
}
}
还有:
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
MyAuthenticationToken myAuthenticationToken = (MyAuthenticationToken) authentication;
MyCredentials credentials = (MyCredentials) myAuthenticationToken.getCredentials();
if (credentials.getPassword().equals("sesamOeffneDich") && credentials.getSecondSecret().equals(MyAuthenticationToken.SECOND_SECRET)){
myAuthenticationToken.setAuthenticated(true);
return myAuthenticationToken;
}else{
throw new BadCredentialsException("Bad credentials supplied!");
}
}
@Override
public boolean supports(Class<?> authentication) {
return MyAuthenticationToken.class.isAssignableFrom(authentication);
}
}
【问题讨论】:
标签: java spring spring-security authorization