gpt4 book ai didi

基于请求参数的Spring安全认证

转载 作者:IT老高 更新时间:2023-10-28 13:52:38 25 4
gpt4 key购买 nike

我正在处理的应用程序已经有 Spring Security 来处理基于表单的身份验证。现在的要求是通过外部服务以编程方式登录用户如果在请求参数之一中找到 token 。

换句话说,如果存在特定的请求参数,比如“ token ”,它需要使用该 token 调用外部服务来验证它是否是有效 token 。如果是,则用户将登录。

我不知道如何以及在何处“触发”或“连接到”Spring Security 以检查此参数并进行验证,然后在适当的时候对用户进行身份验证,因为没有登录表单。我认为 Spring Security 中应该有一些可以扩展或定制的东西来做到这一点?

我查看了 Spring Security 文档,想知道 AbstractPreAuthenticatedProcessingFilter 是否是正确的开始?

最佳答案

我的应用程序中有类似的设置。据我所知,以下是基本要素:

您需要像这样创建一个 AuthenticationProvider:

public class TokenAuthenticationProvider implements AuthenticationProvider {

@Autowired private SomeService userSvc;

@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
if (auth.isAuthenticated())
return auth;

String token = auth.getCredentials().toString();
User user = userSvc.validateApiAuthenticationToken(token);
if (user != null) {
auth = new PreAuthenticatedAuthenticationToken(user, token);
auth.setAuthenticated(true);
logger.debug("Token authentication. Token: " + token + "; user: " + user.getDisplayName());
} else
throw new BadCredentialsException("Invalid token " + token);
return auth;
}
}

您还需要创建一个 Filter 以将自定义参数转换为身份验证 token :

public class AuthenticationTokenFilter implements Filter {


@Override
public void init(FilterConfig fc) throws ServletException {

}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain fc) throws IOException, ServletException {
SecurityContext context = SecurityContextHolder.getContext();
if (context.getAuthentication() != null && context.getAuthentication().isAuthenticated()) {
// do nothing
} else {
Map<String,String[]> params = req.getParameterMap();
if (!params.isEmpty() && params.containsKey("auth_token")) {
String token = params.get("auth_token")[0];
if (token != null) {
Authentication auth = new TokenAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
}

fc.doFilter(req, res);
}

@Override
public void destroy() {

}

class TokenAuthentication implements Authentication {
private String token;
private TokenAuthentication(String token) {
this.token = token;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return new ArrayList<GrantedAuthority>(0);
}
@Override
public Object getCredentials() {
return token;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return null;
}
@Override
public boolean isAuthenticated() {
return false;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
}
@Override
public String getName() {
// your custom logic here
}
}

}

您需要为这些创建 bean:

<beans:bean id="authTokenFilter" class="com.example.security.AuthenticationTokenFilter" scope="singleton" />
<beans:bean id="tokenAuthProvider" class="com.example.security.TokenAuthenticationProvider" />

最后,您需要将这些 bean 连接到您的安全配置中(相应地进行调整):

<sec:http >
<!-- other configs here -->
<sec:custom-filter ref="authTokenFilter" after="BASIC_AUTH_FILTER" /> <!-- or other appropriate filter -->
</sec:http>

<sec:authentication-manager>
<!-- other configs here -->
<sec:authentication-provider ref="tokenAuthProvider" />
</sec:authentication-manager>

可能还有另一种方法,但这绝对有效(目前使用 Spring Security 3.1)。

关于基于请求参数的Spring安全认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19791406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com