我是Spring Security的新用戶,所以請原諒我,如果這是直截了當的。預認證並將用戶名轉發到默認身份驗證提供商
我們正在重寫遺留Web應用程序的UI層。我們決定新的UI層將基於Spring Security和Spring Security來處理安全和授權。
我一直在尋找在新的應用程序中設置安全模擬我們在以前的應用程序中。在舊的應用程序,我們基本上有用戶在兩個入口點:
- 內部用戶通過其 執行使用客戶端LDAP服務器的實際驗證HTTP基本身份驗證驗證。 這個認證機制是在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使用特定的用戶名/密碼以最少侵入的方式對默認身份驗證提供程序執行登錄,最好不要使用過多的黑客(舊應用程序使用的)。在解決方案
注:雖然拉爾夫的解決方案似乎工作,特別是這部分:
我認爲使用PreAuthenticatedAuthenticationProvider和preAuthenticatedUserDetailsService變量設置爲您在內存AuthenticationUserDetailsService來做應該是要走的路。
但是,它也似乎與CSRF保護玩得很糟糕。當我登錄並重定向到主頁時,來自此頁面的任何HTTP POST都將通過CSRF檢查。 POST'ing之前的主頁的後續GET修復了問題,所以Spring似乎不恰當地覆蓋了當前CSRF令牌。我發現一個詳細說明問題的bug report。儘管它聲稱是固定的,但我還沒有能夠解決它。雖然錯誤報告鏈接到論壇中的解決方法,但我習慣於遵循似乎可行的解決方法。
的竅門是在AuthenticationManager
注入你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:/";
}
}
你有沒有在AbstractPreAuthenticatedProcessingFilter.doAuthenticate中設置斷點來檢查這個方法是否被調用? – Ralph
是的,它被調用。 –