gpt4 book ai didi

java - 预验证并将用户名转发给默认验证提供程序

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:05:59 24 4
gpt4 key购买 nike

我是 Spring Security 的新手,如果这是直截了当的,请原谅我。

我们正在重写遗留网络应用程序的 UI 层。我们决定新的 UI 层将基于 Spring MVC 和 Spring Security 来处理安全和授权。

我一直在考虑在新应用程序中设置安全性以模仿我们在以前的应用程序中的安全性。在旧应用中,我们基本上有两个用户入口点:

  • 内部用户通过 HTTP 基本身份验证进行身份验证使用客户端 LDAP 服务器执行实际身份验证。这种身份验证机制是在 JBoss 服务器上配置的,所以是容器管理。
  • 外部用户通过验证凭据的第三方身份验证服务登录。外部用户角色存储在 LDAP 服务器中。当第三方身份验证服务对凭据进行身份验证时,将使用用户名和硬编码密码在 JBoss 配置的安全域上对它们进行身份验证,以便加载它们的角色。

我想我会尝试在 Spring Security 中模仿这个功能,但到目前为止还不够。我在测试中使用内存中身份验证提供程序代替 LDAP,因为它更容易。我有适用于内部用户的 http 基本身份验证。

我已经尝试子类化 AbstractPreAuthenticatedProcessingFilter 并通过它提供凭据,但它似乎确实将凭据正确转发给“默认”身份验证提供程序。

<http>
...
<http-basic />
<custom-filter position="PRE_AUTH_FILTER" ref="ExternalLoginFilter" />
</http>

<beans:bean id="ExternalLoginFilter" class="com.foo.ExternalLoginPreAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="internal-user" password="password" authorities="ROLE_USER, ROLE_INTERNAL" />
<user name="external-user" password="password" authorities="ROLE_USER, ROLE_EXTERNAL" />
</user-service>
</authentication-provider>
</authentication-manager>`

这是我的 ExternalLoginPreAuthenticationFilter:

public class ExternalLoginPreAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest req) {
return "password";
}

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest req) {
HttpSession session = req.getSession(false);
if(session != null){
return session.getAttribute("app.external-user.username");
}
return null;
}

我也尝试像一些示例建议的那样设置“preAuthenticatedAuthenticationProvider”,但这似乎期望我的 ExternalLoginPreAuthenticationFilter 也已解析用户角色。

关于如何配置 Spring MVC 以允许上述场景的任何想法?基本上,我需要能够告诉 Spring Security 以侵入性最小的方式使用特定的用户名/密码针对默认身份验证提供程序执行登录,最好不要有太多 hack(旧应用程序使用的)。

解决方案注意事项:虽然 Ralph 的解决方案似乎有效,但特别是这部分:

I think using the PreAuthenticatedAuthenticationProvider and set the preAuthenticatedUserDetailsService variable to your in memory AuthenticationUserDetailsService should be the way to go.

不过,它在 CSRF 保护方面似乎也表现不佳。当我登录并被重定向到主页时,来自该页面的任何 HTTP POST 都将无法通过 CSRF 检查。在 POST 之前对主页的后续 GET 解决了这个问题,因此 Spring 似乎以某种方式不正确地覆盖了当前的 CSRF token 。我找到了一个 bug report详细说明问题。尽管它声称已修复,但我无法解决它。虽然错误报告链接到论坛中的解决方法,但我习惯于使用以下似乎有效的解决方法。

诀窍是将 AuthenticationManager 注入(inject)到您的 Controller 中并自己进行登录:

@Controller
@RequestMapping(value = "/external-login")
public class ExternalLoginController {

private AuthenticationManager authenticationManager;

@Autowired
public ExternalLoginController(AuthenticationManager authenticationManager){
this.authenticationManager = authenticationManager;
}

// ...

@RequestMapping(method = RequestMethod.POST)
public String login(){
// Do this after third-party authentication service accepts credentials
String username = "external-user"; // or whatever username was authenticated by third-party
UsernamePasswordAuthenticationToken credentials = new UsernamePasswordAuthenticationToken(username, "password");
Authentication auth = authenticationManager.authenticate(credentials);
SecurityContextHolder.getContext().setAuthentication(auth);

return "redirect:/";
}
}

最佳答案

问题是,AuthenticationProvider 是在 AuthenticationManager 中通过提供的身份验证凭证类(通常是 AbstractAuthenticationToken 的子类)选择的).

您的 PreAuthenticationProcessingFilter 将创建一个 PreAuthenticatedAuthenticationToken,它通常由 PreAuthenticatedAuthenticationProvider“使用”。

所以要么:

  • 您注册一个“使用”PreAuthenticatedAuthenticationProvider token 的AuthenticationProvider,然后执行您想要的操作,或者
  • 您更改 PreAuthenticationProcessingFilter 以创建另一种 token (例如 UsernamePasswordAuthenticationToken,它由您使用的“正常”身份验证提供程序“使用”(子类AbstractUserDetailsAuthenticationProvider))

我认为使用 PreAuthenticatedAuthenticationProvider 并将 preAuthenticatedUserDetailsS​​ervice 变量设置为内存中的 AuthenticationUserDetailsS​​ervice 应该是可行的方法。

关于java - 预验证并将用户名转发给默认验证提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21474128/

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