为什么 @AuthenticationPrincipal return 是 Authentication 而不是 principal 对象?
Why does @AuthenticationPrincipal return the Authentication instead of the principal object?
我想在我的控制器方法中使用 @AuthenticationPrincipal
注释检索当前用户。文档说明如下:
Annotation that binds a method parameter or method return value to the Authentication.getPrincipal().
但实际上我得到的是 Authentication
对象而不是 Authentication.getPrincipal()
。
这是我的简单控制器方法:
@RequestMapping("/")
public @ResponseBody String index(@AuthenticationPrincipal final WindowsAuthenticationToken user) {
return String.format("Welcome to the home page, %s!", user.getName());
}
WindowsAuthenticationToken
implements Authentication
. In this implementation getPrincipal
returns a WindowsPrincipal
.
上面的控制器方法有效,但是当我将参数类型更改为 WindowsPrincipal
并尝试访问网站时,出现以下错误页面:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Mar 03 15:13:52 CET 2015
There was an unexpected error (type=Internal Server Error, status=500).
argument type mismatch HandlerMethod details: Controller [pkg.HomeController] Method [public java.lang.String pkg.HomeController.index(waffle.servlet.WindowsPrincipal)] Resolved arguments: [0] [type=waffle.spring.WindowsAuthenticationToken] [value=waffle.spring.WindowsAuthenticationToken@121a2581]
这是我的配置文件:
package pkg;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import waffle.servlet.spi.BasicSecurityFilterProvider;
import waffle.servlet.spi.NegotiateSecurityFilterProvider;
import waffle.servlet.spi.SecurityFilterProvider;
import waffle.servlet.spi.SecurityFilterProviderCollection;
import waffle.spring.NegotiateSecurityFilter;
import waffle.spring.NegotiateSecurityFilterEntryPoint;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint;
@Autowired
private NegotiateSecurityFilter waffleNegotiateSecurityFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(negotiateSecurityFilterEntryPoint).and()
.addFilterBefore(waffleNegotiateSecurityFilter, BasicAuthenticationFilter.class).authorizeRequests()
.anyRequest().fullyAuthenticated();
}
@Bean
public WindowsAuthProviderImpl waffleAuthProvider() {
return new WindowsAuthProviderImpl();
}
@Bean
public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(
final WindowsAuthProviderImpl waffleAuthProvider) {
return new NegotiateSecurityFilterProvider(waffleAuthProvider);
}
@Bean
public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl waffleAuthProvider) {
return new BasicSecurityFilterProvider(waffleAuthProvider);
}
@Bean
public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(
final NegotiateSecurityFilterProvider negotiateSecurityFilterProvider,
final BasicSecurityFilterProvider basicSecurityFilterProvider) {
final SecurityFilterProvider[] providers = { negotiateSecurityFilterProvider, basicSecurityFilterProvider };
return new SecurityFilterProviderCollection(providers);
}
@Bean
public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(
final SecurityFilterProviderCollection waffleSecurityFilterProviderCollection) {
final NegotiateSecurityFilterEntryPoint entryPoint = new NegotiateSecurityFilterEntryPoint();
entryPoint.setProvider(waffleSecurityFilterProviderCollection);
return entryPoint;
}
@Bean
public NegotiateSecurityFilter waffleNegotiateSecurityFilter(
final SecurityFilterProviderCollection waffleSecurityFilterProviderCollection) {
final NegotiateSecurityFilter filter = new NegotiateSecurityFilter();
filter.setProvider(waffleSecurityFilterProviderCollection);
return filter;
}
}
为什么行为与应有的不同?
因为你的WindowsPrincipal
实现了Principal
。删除 implements 子句,它将再次工作。我遇到了同样的问题,这解决了它。
我的主体对象没有实现 UserDetails
。因为 WindowsPrincipal
是外部库的 class,所以我无法对其进行任何更改。最后,我创建了一个新过滤器,将 WindowsPrincipal
包装在实现 UserDetails
的 class 中。现在我使用 @AuthenticationPrincipal
.
得到了正确的主体对象
我想在我的控制器方法中使用 @AuthenticationPrincipal
注释检索当前用户。文档说明如下:
Annotation that binds a method parameter or method return value to the Authentication.getPrincipal().
但实际上我得到的是 Authentication
对象而不是 Authentication.getPrincipal()
。
这是我的简单控制器方法:
@RequestMapping("/")
public @ResponseBody String index(@AuthenticationPrincipal final WindowsAuthenticationToken user) {
return String.format("Welcome to the home page, %s!", user.getName());
}
WindowsAuthenticationToken
implements Authentication
. In this implementation getPrincipal
returns a WindowsPrincipal
.
上面的控制器方法有效,但是当我将参数类型更改为 WindowsPrincipal
并尝试访问网站时,出现以下错误页面:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Mar 03 15:13:52 CET 2015
There was an unexpected error (type=Internal Server Error, status=500).
argument type mismatch HandlerMethod details: Controller [pkg.HomeController] Method [public java.lang.String pkg.HomeController.index(waffle.servlet.WindowsPrincipal)] Resolved arguments: [0] [type=waffle.spring.WindowsAuthenticationToken] [value=waffle.spring.WindowsAuthenticationToken@121a2581]
这是我的配置文件:
package pkg;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import waffle.servlet.spi.BasicSecurityFilterProvider;
import waffle.servlet.spi.NegotiateSecurityFilterProvider;
import waffle.servlet.spi.SecurityFilterProvider;
import waffle.servlet.spi.SecurityFilterProviderCollection;
import waffle.spring.NegotiateSecurityFilter;
import waffle.spring.NegotiateSecurityFilterEntryPoint;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint;
@Autowired
private NegotiateSecurityFilter waffleNegotiateSecurityFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling().authenticationEntryPoint(negotiateSecurityFilterEntryPoint).and()
.addFilterBefore(waffleNegotiateSecurityFilter, BasicAuthenticationFilter.class).authorizeRequests()
.anyRequest().fullyAuthenticated();
}
@Bean
public WindowsAuthProviderImpl waffleAuthProvider() {
return new WindowsAuthProviderImpl();
}
@Bean
public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(
final WindowsAuthProviderImpl waffleAuthProvider) {
return new NegotiateSecurityFilterProvider(waffleAuthProvider);
}
@Bean
public BasicSecurityFilterProvider basicSecurityFilterProvider(final WindowsAuthProviderImpl waffleAuthProvider) {
return new BasicSecurityFilterProvider(waffleAuthProvider);
}
@Bean
public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(
final NegotiateSecurityFilterProvider negotiateSecurityFilterProvider,
final BasicSecurityFilterProvider basicSecurityFilterProvider) {
final SecurityFilterProvider[] providers = { negotiateSecurityFilterProvider, basicSecurityFilterProvider };
return new SecurityFilterProviderCollection(providers);
}
@Bean
public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(
final SecurityFilterProviderCollection waffleSecurityFilterProviderCollection) {
final NegotiateSecurityFilterEntryPoint entryPoint = new NegotiateSecurityFilterEntryPoint();
entryPoint.setProvider(waffleSecurityFilterProviderCollection);
return entryPoint;
}
@Bean
public NegotiateSecurityFilter waffleNegotiateSecurityFilter(
final SecurityFilterProviderCollection waffleSecurityFilterProviderCollection) {
final NegotiateSecurityFilter filter = new NegotiateSecurityFilter();
filter.setProvider(waffleSecurityFilterProviderCollection);
return filter;
}
}
为什么行为与应有的不同?
因为你的WindowsPrincipal
实现了Principal
。删除 implements 子句,它将再次工作。我遇到了同样的问题,这解决了它。
我的主体对象没有实现 UserDetails
。因为 WindowsPrincipal
是外部库的 class,所以我无法对其进行任何更改。最后,我创建了一个新过滤器,将 WindowsPrincipal
包装在实现 UserDetails
的 class 中。现在我使用 @AuthenticationPrincipal
.