2012-01-29 86 views
3

我试图找出如何让Spring安全返回UserDetails对象为匿名用户本次通话:的Spring Security 3.1和返回匿名的UserDetails

SecurityContextHolder.getContext().getAuthentication().getPrincipal() 

我知道,如果没有特殊的配置,该呼叫将返回一个字符串,而不是使用自定义的UserDetailsS​​ervice实现创建的UserDetails对象,但我宁愿不经常检查“if(principal instanceof String)”。有没有办法做到这一点与Spring配置 - 一种方式,将匿名UserDetails对象存储在用户的会话上下文,直到他们登录?表面上,我想为每个客人提供一个独特的匿名UserDetails,这样我就可以跟踪它的个人用法。

我也注意到我用“PreAuthorize”注释保证的方法似乎没有兑现匿名用户的hasRole检查。我敢肯定,这是我做错事的一个症状。这里有一个例子:

@RequestMapping(value = "/almanac/new", method = RequestMethod.GET) 
@PreAuthorize("hasRole('ROLE_ADMIN')") 
public String newSetup(ModelMap model) { 

这是我的弹簧安全上下文(除了封闭的bean节点之外,是完整的)。你可以注意到我试图启用“匿名”

<debug /> 
<http pattern="/js/**" security="none" /> 
<http pattern="/css/**" security="none" /> 
<http pattern="/images/**" security="none" /> 
<http pattern="/loggedout.jsp" security="none"/> 
<http name="httpSiteMap" use-expressions="true"> 
    <custom-filter ref="almanacUsrPwdAuthProcFilter" before="FORM_LOGIN_FILTER"/> 
    <intercept-url pattern="/login*" access="isAnonymous()" /> 
    <intercept-url pattern="/home/**" access="hasRole('ROLE_USER')" /> 
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/**" access="isAnonymous()" /> 
    <form-login login-page="/login.jsp" 
       default-target-url="/home.htm" 
       always-use-default-target="false" /> 
    <logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/> 
    <session-management invalid-session-url="/timeout.jsp"> 
     <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> 
    </session-management> 
    <anonymous enabled="true" /> 
</http> 

<global-method-security pre-post-annotations="enabled" secured-annotations="enabled" /> 

<authentication-manager alias="mainAuthMgr"> 
    <authentication-provider ref="almanacAuthenticationProvider"/> 
</authentication-manager> 

根据你在这里看到的代码的任何其他建议将受到欢迎。

+0

你能解释一下你想使用匿名UserDetails吗?它包含哪些数据以及如何使用它?你不需要'',因为这是默认值。您应该看到在调试日志中报告的AnonymousAuthenticationFilter作为确认。 – 2012-01-29 18:57:14

+0

我试图避免让“getPrincipal()”调用返回一个字符串。我希望这个调用只返回一个UserDetails实现,无论是匿名身份验证还是用户登录。我想避免为exampleof String测试“getPrincipal()”的返回值。当然,由于文档在某些领域非常模糊,特定的配置点的信息在很多章节中都很细致地分布,所以很难判断这是您应该做的事情,还是仅仅处理比较实例。 – ogradyjd 2012-01-29 19:28:40

回答

3

对于匿名用户,你想从UserDetails中提取什么数据,你还没有真正给出太多的细节。如果您只想检查用户名,则可以使用​​。在任何情况下,如果您需要更详细地访问安全上下文,最好使用自定义接口将您的应用程序代码与Spring Security类分离(请参阅my answer on using a security context accessor)。这样,您应该只在一个地方检查委托人的类型,而不是重复您要访问用户数据的“无处不在”检查。

如果您绝对希望在身份验证对象中始终拥有相同的主体类型(无论用户是否是匿名用户),则必须通过名称空间禁用匿名身份验证,并添加一个自定义过滤器来执行此作业在现有的AnonymousAuthenticationFilter上。

+0

我必须误解一些非常基本的东西,然后如果我不应该做你说的话,因为方法安全性不能使用默认的匿名身份验证。你可以从我的代码中看到,我启用了全局方法安全性,但是我可以在没有登录的情况下请求调用“newSetup”方法的URL,并且我很确定我没有指定任何匿名用户应该拥有ROLE_ADMIN (如果我想现在就不知道该怎么办)。 我将按照您的建议实施安全访问器外观。 – ogradyjd 2012-01-29 22:18:31

+0

从问题的第二部分可以看出,它与匿名身份验证或访问安全上下文的需求有关。对于非匿名用户,该注释是否完全适用?如果没有,这可能是一个应用程序上下文可见性问题 - 请参阅[本FAQ](http://static.springsource.org/spring-security/site/faq/faq.html#faq-method-security-in-web-上下文)。 – 2012-01-29 22:42:42

+0

[这个问题](http://stackoverflow.com/questions/2114814/spring-security-spring-mvc-configuration)也讨论了在MVC控制器中使用安全注解的问题。 – 2012-01-29 22:49:13