Spring Security 未授权预认证
我正在尝试实现预身份验证场景,但遇到了一些问题。 这是我的安全上下文文件..
<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"/>
这是自定义的 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 是一个自定义用户对象,它扩展了 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来您实际上并没有实现
PreAuthenticatedGrantedUserDetailsService
类所需的功能。您应该实现函数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 functionloadUserDetails(authenication_token)
because that is the function actually used to get theUserDetails
object for Spring. Since you don't have this function implemented, Spring will never have a way of getting theUserDetails
. Please see the documentation for more details.