Spring Security 未授权预认证

发布于 2024-12-10 00:48:35 字数 5237 浏览 0 评论 0原文

我正在尝试实现预身份验证场景,但遇到了一些问题。 这是我的安全上下文文件..

<sec:global-method-security secured-annotations="enabled" pre-post-annotations="disabled"/>
<sec:http pattern="/static/**" security="none" />
<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService">
        <bean id="userDetailsServiceWrapper"
            class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="userDetailsService"/>
        </bean>
    </property>
</bean>

<bean id="userDetailsService"
    class="com.myapp.UserDetailsServiceImpl"/>

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

<sec:http auto-config="false" use-expressions="true">
    <sec:intercept-url pattern="/index.htm" access="permitAll"/>
    <sec:intercept-url pattern="/logoff.html" access="permitAll"/>
    <sec:intercept-url pattern="/profile/**" access="hasAnyRole('ROLE_PROFILEUSER', 'ROLE_ADMIN')"/>
    <sec:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
    <sec:intercept-url pattern="/**" access="isAuthenticated()"/>
    <!-- <sec:form-login login-page="/login.html"  default-target-url="/home.html" authentication-failure-url="/login.html"/> -->
    <sec:logout logout-url="/logoff.html"/> 
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="channelSecureFilter" />
</sec:http>

<bean id="channelSecureFilter"
    class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">

    <property name="principalRequestHeader" value="SM_UNIVERSAL_ID"/>   
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="invalidateSessionOnPrincipalChange" value="true"/>
</bean>


<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="decisionVoters">
        <list>
            <ref local="roleVoter"/>
            <ref local="authenticatedVoter"/>
        </list>
    </property>

</bean>

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <property name="rolePrefix" value="ROLE_"/>
</bean>

<bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"/>

这是自定义的 UserDetailsS​​erviceImpl

@Component
public class UserDetailsServiceImpl extends PreAuthenticatedGrantedAuthoritiesUserDetailsService implements UserDetailsService{
   @Autowired PersonService personService;


@Override
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {
           //I dont think anything is needed here... right?
    return null;
}

@Override
protected UserDetails createuserDetails(Authentication token,
        Collection<? extends GrantedAuthority> role){

    Person lp = PersonService.findPersonByNetId(token.getName());

    PreAuthenticatedGrantedAuthoritiesUserDetailsService test = new PreAuthenticatedGrantedAuthoritiesUserDetailsService();


    if(lp==null){
        role.add(new SimpleGrantedAuthority("ROLE_USER"));
        return new LLUser(token.getName(),"N/A", true, true, true, true, role, null);
    }
    else{
        boolean enabled = (lp.getIsActive()==1)?true:false;
        boolean credentialsNonExpired = (lp.getIsActive()==1)?true:false;
        //test whehther deactivate date is null or deactivate data is greater than current date
        boolean accountNonExpired = ((lp.getDeactivateDate()==null)||(lp.getDeactivateDate().compareTo(new Date())>0))?true:false;
        boolean accountNonLocked = (lp.getIsActive()==1)?true:false;
        Integer personId = lp.getPerson().getId();

        if(lp.getLlRole()!=null){
            if(lp.getLlRole()==10)
            {   
                role.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                role.add(new SimpleGrantedAuthority("ROLE_PROFILEUSER"));
            }
            if(lp.getLlRole()==25)
                role.add(new SimpleGrantedAuthority("ROLE_PROFILEUSER"));
            }

        role.add(new SimpleGrantedAuthority("ROLE_USER"));

        return new LLUser(token.getName(),"N/A", enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, role, personId);
    }

}

}

LLUser 是一个自定义用户对象,它扩展了 Spring 的用户对象。所以,现在的问题是,

1)。我似乎无法将 SimpleGrantedauthoriy 添加到“角色”集合中。我收到以下错误,但我无法理解它,因为 SimplegGrantedAuthority 是 GrantedAuthority 的实现,对吗?

the method add(capture#1-of ? extends GrantedAuthority) in the type collection<capture#1-of ? extends GrantedAuthority> is not applicable for the arguments (SimpleGrantedAuthority)

2)。我非常确定我初始化自定义 User 对象的方式不正确,因为没有来自请求的密码,并且 User 类不知道要与什么进行比较?

另外,请查看我的上下文配置文件,并让我知道是否有任何冗余元素或者我是否遗漏了任何重要内容。提前致谢。

I am trying to implement pre-authentication scenario and I am running into few issues..
This is my security context file..

<sec:global-method-security secured-annotations="enabled" pre-post-annotations="disabled"/>
<sec:http pattern="/static/**" security="none" />
<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService">
        <bean id="userDetailsServiceWrapper"
            class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="userDetailsService"/>
        </bean>
    </property>
</bean>

<bean id="userDetailsService"
    class="com.myapp.UserDetailsServiceImpl"/>

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

<sec:http auto-config="false" use-expressions="true">
    <sec:intercept-url pattern="/index.htm" access="permitAll"/>
    <sec:intercept-url pattern="/logoff.html" access="permitAll"/>
    <sec:intercept-url pattern="/profile/**" access="hasAnyRole('ROLE_PROFILEUSER', 'ROLE_ADMIN')"/>
    <sec:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
    <sec:intercept-url pattern="/**" access="isAuthenticated()"/>
    <!-- <sec:form-login login-page="/login.html"  default-target-url="/home.html" authentication-failure-url="/login.html"/> -->
    <sec:logout logout-url="/logoff.html"/> 
    <sec:custom-filter position="PRE_AUTH_FILTER" ref="channelSecureFilter" />
</sec:http>

<bean id="channelSecureFilter"
    class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">

    <property name="principalRequestHeader" value="SM_UNIVERSAL_ID"/>   
    <property name="authenticationManager" ref="authenticationManager"/>
    <property name="invalidateSessionOnPrincipalChange" value="true"/>
</bean>


<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <property name="decisionVoters">
        <list>
            <ref local="roleVoter"/>
            <ref local="authenticatedVoter"/>
        </list>
    </property>

</bean>

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <property name="rolePrefix" value="ROLE_"/>
</bean>

<bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"/>

and this is the custom UserDetailsServiceImpl

@Component
public class UserDetailsServiceImpl extends PreAuthenticatedGrantedAuthoritiesUserDetailsService implements UserDetailsService{
   @Autowired PersonService personService;


@Override
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {
           //I dont think anything is needed here... right?
    return null;
}

@Override
protected UserDetails createuserDetails(Authentication token,
        Collection<? extends GrantedAuthority> role){

    Person lp = PersonService.findPersonByNetId(token.getName());

    PreAuthenticatedGrantedAuthoritiesUserDetailsService test = new PreAuthenticatedGrantedAuthoritiesUserDetailsService();


    if(lp==null){
        role.add(new SimpleGrantedAuthority("ROLE_USER"));
        return new LLUser(token.getName(),"N/A", true, true, true, true, role, null);
    }
    else{
        boolean enabled = (lp.getIsActive()==1)?true:false;
        boolean credentialsNonExpired = (lp.getIsActive()==1)?true:false;
        //test whehther deactivate date is null or deactivate data is greater than current date
        boolean accountNonExpired = ((lp.getDeactivateDate()==null)||(lp.getDeactivateDate().compareTo(new Date())>0))?true:false;
        boolean accountNonLocked = (lp.getIsActive()==1)?true:false;
        Integer personId = lp.getPerson().getId();

        if(lp.getLlRole()!=null){
            if(lp.getLlRole()==10)
            {   
                role.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                role.add(new SimpleGrantedAuthority("ROLE_PROFILEUSER"));
            }
            if(lp.getLlRole()==25)
                role.add(new SimpleGrantedAuthority("ROLE_PROFILEUSER"));
            }

        role.add(new SimpleGrantedAuthority("ROLE_USER"));

        return new LLUser(token.getName(),"N/A", enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, role, personId);
    }

}

}

LLUser is a custom user object that extends Spring's user object. So, now the issues are,

1). I cannot seem to add SimpleGrantedauthoriy to the "role" collection. I am getting following error and I can't understand it because SimplegGrantedAuthority is an implementation of GrantedAuthority right?

the method add(capture#1-of ? extends GrantedAuthority) in the type collection<capture#1-of ? extends GrantedAuthority> is not applicable for the arguments (SimpleGrantedAuthority)

2). I am very sure my way of initializing the custom User object is incorrect because, there is no password coming from the request and User class will not know what to compare against?

Also, please look at my context config file and let me know if there are any redundant elements or if I am missing anything important. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清醇 2024-12-17 00:48:35

看来您实际上并没有实现 PreAuthenticatedGrantedUserDetailsS​​ervice 类所需的功能。您应该实现函数 loadUserDetails(authenication_token),因为该函数实际用于获取 Spring 的 UserDetails 对象。由于您没有实现此函数,Spring 将永远无法获取UserDetails。请参阅 文档了解更多详细信息。

It seems you aren't actually implementing the functions necessary for the PreAuthenticatedGrantedUserDetailsService class. You should be implementing the function loadUserDetails(authenication_token) because that is the function actually used to get the UserDetails object for Spring. Since you don't have this function implemented, Spring will never have a way of getting the UserDetails. Please see the documentation for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文