SpringSecurity - 自定义自动身份验证 [英] SpringSecurity - Custom automatic authentication

查看:128
本文介绍了SpringSecurity - 自定义自动身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的方案:




  • 网络应用程序为许多应用程序执行一种SSO

  • 登录用户而不是点击链接,应用程序发布了一个包含用户信息(名称,pwd [无用],角色)的文章到适当的应用程序

  • 我正在实施SpringSecurity在其中一个应用程序中受益于它的权力(会话中的权限,其类提供的方法等)



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



我在看预身份验证过滤器,但我不是确定这是正确的选择。似乎这些对象在主体已经在会话中时被使用,由一些先前的认证机制放置(是不是?)。



我认为,一旦确定了正确的过滤器,我应该在以下内容中执行:

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

SecurityContext sc = SecurityContextHolder.getContext();
身份验证a = new UsernamePasswordAuthenticationToken(userName,userPwd,ga);
a = authenticationManager.authenticate(a);
sc.setAuthentication(a);

这是解决问题的正确方向吗?你有什么建议可以帮我找到遗漏的东西吗?



谢谢大家,



Luca



ADDITION:



您好Xearxess!很抱歉再次打扰你,但似乎根据SpringSecurity 2.0.4的代码翻译比我想象的更难:S问题是XML ...我尝试了不同的配置,但我总是遇到命名空间问题,缺少属性等等...

 <?xml version =1.0encoding =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 =/ logoutlogout-success-url =http://milan-ias-vs.usersad.everis.int/DMTest/invalidate-session =true />
< security:custom-filter position =PRE_AUTH_FILTERref =preAuthenticatedProcessingFilter/>
< / security:http>

< bean id =preAuthenticatedProcessingFilterclass =it.novartis.ram.authentication.PreAuthenticatedProcessingFilter>
< custom-filter position =PRE_AUTH_FILTER/>
< property name =authenticationManagerref =authenticationManager/>
< / bean>

< bean id =preauthAuthProviderclass =org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider>
< property name =preAuthenticatedUserDetailsS​​ervice>
< bean class =it.novartis.ram.authentication.PreAuthenticatedUserDetailsS​​ervice/>
< / property>
< / bean>

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

< / beans>

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



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



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



Luca

解决方案

是的,预身份验证方案正是您所需要的。


当主要的
已经在会话中时,预计会使用这些对象,由一些先前的身份验证机制放置
(是吗?)。


不是真的,您可以使用预身份验证来创建 <$ c来自请求的$ c> PreAuthenticatedAuthenticationToken ,如您所愿。只需执行我在其他问题中描述的一些内容



首先extend AbstractPreAuthenticatedProcessingFilter 从请求中获取用户名和角色:

  public class MyPreAuthenticatedProcessingFilter 
extends AbstractPreAuthenticatedProcessingFilter {

public MyPreAuthenticatedProcessingFilter(
AuthenticationManager authenticationManager){
setAuthenticationDetailsS​​ource(new MyAuthenticationDetailsS​​ource());
}

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request){
returnAnonymous;
}

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request){
returnN / A;
}

公共静态类MyAuthenticationDetailsS​​ource实现
AuthenticationDetailsS​​ource< HttpServletRequest,MySessionUserDetails> {
//角色可能应该以某种方式加密
静态最终字符串ROLES_PARAMETER =pre_auth_roles;

@Override
public MySessionUserDetails buildDetails(HttpServletRequest req){
//为pre-auth数据创建容器
返回新的MySessionUserDetails(req.getParameter(ROLES_PARAMETER)) ;
}
}
}

MySessionUserDetails 类将弹出的角色分配给 SimpleGrantedAuthority 或任何其他 GrantedAuthority 实施。此外,建议使用List并优于 GrantedAuthority []



其次,实现 AuthenticationUserDetailsS​​ervice

  public class MyPreAuthenticatedUserDetailsS​​ervice实现
AuthenticationUserDetailsS​​ervice< PreAuthenticatedAuthenticationToken> {

@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
throws UsernameNotFoundException {
MySessionUserDetails sessionUserDetails =
(MySessionUserDetails)token.getDetails();
列表< GrantedAuthority> authorities = sessionUserDetails.getAuthorities();
返回新用户(token.getName(),N / A,true,true,true,true,authority);
}
}

然后在你的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 =authenticationManagerref =authenticationManager/>
< / bean>

< bean id =preauthAuthProviderclass =org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider>
< property name =preAuthenticatedUserDetailsS​​ervice>
< bean class =com.example.MyPreAuthenticatedUserDetailsS​​ervice/>
< / property>
< / bean>

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

瞧!您应该已经过身份验证 用户 在您的应用程序中使用的委托人。



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


This is my scenario:

  • a web-app perform a sort-of SSO for many applications
  • logged-in user than click on a link and the app makes a post with user informations (name, pwd [useless], roles) toward the proper application
  • I am implementing SpringSecurity on one of these application to benefit from its power (authorities in session, methods provided by its classes, etc)

So, I need to develop a custom filter - I guess - that is able to retrieve user informations from request, retrieve from database, through a custom DetailsUserService, further information about the user (email, etc...) and then perform authentication of that user, according to the role retrieved from the request.

I was looking at Pre-Authentication filters, but I'm not sure that it is the right choice. It seems that those object are expected to be used when the principal is already in session, put by some previous authentication machanism (is it right?).

I think that, once identified the correct filter, I should need to perform within something like:

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);

Is it the proper direction to solve my problem? Do you have suggestions to help me find what's missing?

Thank you all,

Luca

ADDITION:

Hi Xearxess! Sorry to bother you again but it seems that the translation of your code according to SpringSecurity 2.0.4 is more difficult than I thought :S The problem is the XML... I tried different configuration but I ran always into namespace problems, missing attributes, etc...

<?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>

The 2 rows referencing CUSTOM-FILTER element are two different tries, both of them signed as error. How can I specify the position of my filter as a property?

Also the authentication provider reference on auth manager definition is marked as error. I think that I need to specify it like a property too, right?

Hope you can give me the last push ;) Thank you again,

Luca

解决方案

Yes, Pre-Authentication Scenarios are exactly what you are looking for.

It seems that those object are expected to be used when the principal is already in session, put by some previous authentication machanism (is it right?).

Not really, you can use Pre-Authentication to create PreAuthenticatedAuthenticationToken from request, as you want. Just do few things I described in another question.

First extend AbstractPreAuthenticatedProcessingFilter to obtain username and roles from request:

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 class will split spring with roles to List of SimpleGrantedAuthority or any other GrantedAuthority implementation. Also, List is recommended and superior to GrantedAuthority[].

Second, implement 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);
  }
}

Then in your XML connect blocks together:

<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>

And voila! You should have authenticated User principal to use in your application.

Code I written here requires Spring Security 3.1 which I strongly recommend if you're about to using it (it does requrire Spring 3.0.7+). Also, Spring Security reference manual is your friend!

这篇关于SpringSecurity - 自定义自动身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆