2012-09-18 40 views
5

这是我的情景:SpringSecurity - 自定义自动认证

  • 一个web应用程序对于许多应用进行SSO一个排序的
  • 登录的用户不是点击一个链接和应用发出后与用户信息(名称,pwd [无用],角色)对正确的应用程序
  • 我在这些应用程序之一实施SpringSecurity受益于其权力(权限在会话中,其类提供的方法等)

所以,我需要开发一个自定义过滤器 - 我想 - 这是能够检索请求的用户信息,从数据库中检索,通过自定义DetailsUserService,关于用户(电子邮件等的进一步信息... ),然后根据从请求中检索的角色执行该用户的身份验证。

我在看Pre-Authentication过滤器,但我不确定它是否是正确的选择。似乎这些对象预计会在委托人已经在会议中使用,并被一些以前的认证机制所采用(是不是?)。

我认为,一旦确定正确的过滤器,我应该需要类似中执行:

GrantedAuthority[] ga= new GrantedAuthority[1]; 
ga[0] = new GrantedAuthorityImpl(myUser.getRole()); 

SecurityContext sc = SecurityContextHolder.getContext(); 
Authentication a = new UsernamePasswordAuthenticationToken(userName, userPwd, ga); 
a = authenticationManager.authenticate(a); 
sc.setAuthentication(a); 

它是正确的方向来解决我的问题呢?你有什么建议可以帮助我找到缺失的东西吗?

谢谢大家,

卢卡

此外:

Xearxess嗨!对不起,再次打扰你,但似乎根据SpringSecurity 2.0.4的代码翻译比我想象的更困难:S问题是XML ...我尝试了不同的配置,但我总是跑进命名空间问题,缺少属性等等...

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> 

    <security:http> 
     <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
     <security:logout logout-url="/logout" logout-success-url="http://milan-ias-vs.usersad.everis.int/DMTest/" invalidate-session="true" /> 
     <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthenticatedProcessingFilter" /> 
    </security:http> 

    <bean id="preAuthenticatedProcessingFilter" class="it.novartis.ram.authentication.PreAuthenticatedProcessingFilter"> 
     <custom-filter position="PRE_AUTH_FILTER"/> 
     <property name="authenticationManager" ref="authenticationManager" /> 
    </bean> 

    <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
     <property name="preAuthenticatedUserDetailsService"> 
      <bean class="it.novartis.ram.authentication.PreAuthenticatedUserDetailsService" /> 
     </property> 
    </bean> 

    <security:authentication-manager alias="authenticationManager"> 
     <security:authentication-provider ref="preauthAuthProvider" /> 
    </security:authentication-manager> 

</beans> 

引用CUSTOM-FILTER元素的2行是两个不同的尝试,它们都被标记为错误。如何将我的过滤器的位置指定为属性?

此外,身份验证管理器定义上的身份验证提供程序引用标记为错误。我认为我需要将它指定为属性,对吧?

希望你能给我最后一次推;) 再次感谢您,

卢卡

回答

11

是,预认证场景是你在寻找什么。

看来,这些目标预计将被用于当主 已经在会议上,由以前的一些认证机理 把(是​​不是)。

并非如此,您可以根据需要使用预认证从请求创建PreAuthenticatedAuthenticationToken。只需do few things I described in another question

首先延伸AbstractPreAuthenticatedProcessingFilter从请求获取的用户名和作用:

public class MyPreAuthenticatedProcessingFilter 
    extends AbstractPreAuthenticatedProcessingFilter { 

    public MyPreAuthenticatedProcessingFilter(
     AuthenticationManager authenticationManager) { 
    setAuthenticationDetailsSource(new MyAuthenticationDetailsSource()); 
    } 

    @Override 
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
    return "Anonymous"; 
    } 

    @Override 
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
    return "N/A"; 
    } 

    public static class MyAuthenticationDetailsSource implements 
     AuthenticationDetailsSource<HttpServletRequest, MySessionUserDetails> { 
    // roles probably should be encrypted somehow 
    static final String ROLES_PARAMETER = "pre_auth_roles"; 

    @Override 
    public MySessionUserDetails buildDetails(HttpServletRequest req) { 
     // create container for pre-auth data 
     return new MySessionUserDetails(req.getParameter(ROLES_PARAMETER)); 
    } 
    } 
} 

MySessionUserDetails类会分裂弹簧与角色列表的SimpleGrantedAuthority或任何其他GrantedAuthority实现。此外,建议使用List并优于GrantedAuthority[]

二,落实AuthenticationUserDetailsService

public class MyPreAuthenticatedUserDetailsService implements 
    AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { 

    @Override 
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) 
     throws UsernameNotFoundException { 
    MySessionUserDetails sessionUserDetails = 
     (MySessionUserDetails) token.getDetails(); 
    List<GrantedAuthority> authorities = sessionUserDetails.getAuthorities(); 
    return new User(token.getName(), "N/A", true, true, true, true, authorities); 
    } 
} 

然后在你的XML连接块一起:

<security:http use-expressions="true"> 
    <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
    <security:custom-filter position="PRE_AUTH_FILTER" 
     ref="myPreAuthenticationFilter" /> 
</security:http> 

<bean id="myPreAuthenticationFilter" 
    class="com.example.MyPreAuthenticatedProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
</bean> 

<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
    <property name="preAuthenticatedUserDetailsService"> 
    <bean class="com.example.MyPreAuthenticatedUserDetailsService" /> 
    </property> 
</bean> 

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider ref="preauthAuthProvider" /> 
</security:authentication-manager> 

瞧!您应该已经认证了User本人在您的应用程序中使用。

我在这里编写的代码需要Spring Security 3.1,如果您即将使用它(它的确需要Spring 3.0.7+),我强烈建议使用它。另外,Spring Security reference manual是你的朋友!

+0

非常感谢Xaerxess!不幸的是,我们坚持使用Spring 2.5.6和Spring Security 2.0.4,但您的建议将对我有所帮助;) – Dolfiz

+0

很遗憾,Spring 3更好,通用并且具有很好的文档。但是上面的大量代码可以回溯到2.X(例如没有泛型)。 – Xaerxess

+0

确实很可惜!但是你写的代码会帮助我。再次感谢您和宝宝共度美好时光;) – Dolfiz

8

为了完整起见,在Spring Security 4中稍微改变了一些东西。例如,强烈建议使用Java配置。通过这种方式,与Spring Boot集成起来更容易。

它遵循与上述答案中给出的XML配置等效的Java配置。

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.addFilterBefore(customAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class) 
      .authenticationProvider(preauthAuthProvider()) 
      .authorizeRequests() 
      .anyRequest().authenticated(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(preauthAuthProvider()); 
    } 

    @Bean 
    public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { 
     PreAuthenticatedAuthenticationProvider preauthAuthProvider = 
      new PreAuthenticatedAuthenticationProvider(); 
       preauthAuthProvider.setPreAuthenticatedUserDetailsService(
        userDetailsServiceWrapper()); 
     return preauthAuthProvider; 
    } 

    @Bean 
    public OnlyRolesPreAuthenticatedUserDetailsService userDetailsServiceWrapper() { 
     OnlyRolesPreAuthenticatedUserDetailsService service = 
      new MyPreAuthenticatedUserDetailsService(); 
     return service; 
    } 

    @Bean 
    public MyPreAuthenticatedProcessingFilter customAuthFilter() throws Exception { 
     MyPreAuthenticatedProcessingFilter filter = new MyPreAuthenticatedProcessingFilter(); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 
} 

我认为上面的代码是值得的,因为在互联网的例子是非常基本的这些细节Spring文档缺乏。

+0

非常感谢!我还没有找到任何解释与java – encastellano

+0

配置很高兴为您提供帮助。 –