问题描述
我想就Spring Security中的问题向您寻求帮助。
我有一个要求,其中我必须根据用户选择的选项验证登录凭证。选项1将通过第三方服务验证登录用户。选项2是使用数据库身份验证级别的正常验证。我该如何实现呢?
I would like to ask for your help regarding my problem in Spring Security.I have a requirement wherein I have to validate a login credential based on the option selected by the user. Option 1 would be validating the logged in user via third party service. Option 2 would be the normal validation using database authentication level. How can I implement this?
推荐答案
- 提供委托的
org.springframework.security.authentication.AuthenticationProvider
的自定义实现对相应后端的身份验证(第三方服务,另一个AuthenticationProvider
等)。 - 将用户选择的选项传递给自定义
AuthenticationProvider
,使其能够选择正确的身份验证后端。 - 配置自定义
AuthenticationProvider
作为默认身份验证提供程序。
- Provide a custom implementation of
org.springframework.security.authentication.AuthenticationProvider
that delegates the authentication to the appropriate backend (third-party service, anotherAuthenticationProvider
, etc.). - Pass the user-selected option to the custom
AuthenticationProvider
to enable it to choose the correct authentication backend. - Configure the custom
AuthenticationProvider
as the default authentication provider.
AuthenticationProvider
是具有单个方法的接口。因此,自定义实现可能如下所示:
AuthenticationProvider
is an interface with a single method. Therefore, a custom implementation may look like:
class DelegatingAuthenticationProvider implements AuthenticationProvider {
@Autowired
private ThirdPartyAuthenticationService service;
@Autowired
@Qualifier("anotherAuthenticationProvider")
private AuthenticationProvider provider;
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
// Get the user selection.
String selection = (String) authentication.getDetails();
// Take action depending on the selection.
Authentication result;
if("ThirdParty".equals(selection)) {
// Authenticate using "service" and generate a new
// Authentication "result" appropriately.
}
else {
// Authenticate using "provider" and generate a new
// Authentication "result" appropriately.
}
return result;
}
}
上面的 AuthenticationProvider
实现从身份验证$的
被调用。这意味着,另一个组件可以访问详细信息
属性中选择用户选择c $ c>对象。据推测,用户选择必须从 HttpServletRequest
中选取,然后在<$之前添加到 Authentication
对象中。 c $ c> AuthenticationProvider 身份验证
和 HttpServletRequest
对象,并在<$ c $之前调用c> AuthenticationProvider 需要实现。
The AuthenticationProvider
implementation above picks up the user selection from the details
property of the Authentication
object. Presumably, the user selection would have to be picked up from the HttpServletRequest
and added to the Authentication
object before the AuthenticationProvider
is invoked. This means, another component that has access to both the Authentication
and HttpServletRequest
objects and is invoked before the AuthenticationProvider
needs to be implemented.
身份验证
对象是由实现 AbstractAuthenticationProcessingFilter
。此类有一个名为 attemptAuthentication
的方法,它接受 HttpServletRequest
对象并返回身份验证
对象。因此,这似乎是实施所需内容的良好候选者。对于基于用户名密码的身份验证,实现类是 UsernamePasswordAuthenticationFilter
。此类返回 UsernamePasswordAuthenticationToken
的新实例,该实例是身份验证
的实现。因此,扩展 UsernamePasswordAuthenticationFilter
的类应该足够了。
The Authentication
object is created by an implementation of AbstractAuthenticationProcessingFilter
. This class has a method named attemptAuthentication
that accepts an HttpServletRequest
object and returns an Authentication
object. So it seems this would be a good candidate for implementing what is needed. For username-password based authentication, the implementation class is UsernamePasswordAuthenticationFilter
. This class returns a new instance of UsernamePasswordAuthenticationToken
, which is an implementation of Authentication
. So, a class extending UsernamePasswordAuthenticationFilter
should be sufficient.
class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
...
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
authentication.setDetails(obtainUserSelection(request));
...
return authentication;
}
}
obtainUserSelection
是一种私有方法,可以让用户从请求中选择。
obtainUserSelection
is a private method that gets the user selection out of the request.
在Spring Security配置中配置 AuthenticationProvider
并过滤实现。具体步骤将根据是使用XML还是Java配置而有所不同。
Configure the AuthenticationProvider
and filter implementations in the Spring Security configuration. The exact steps will vary depending on whether XML or Java configuration is used.
这篇关于在Spring Security中实现自定义身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!