Java Spring Security 3.1并返回匿名用户详细信息

Java Spring Security 3.1并返回匿名用户详细信息,java,spring,spring-mvc,spring-security,anonymous-users,Java,Spring,Spring Mvc,Spring Security,Anonymous Users,我正在尝试找出如何让Spring Security为此调用为匿名用户返回UserDetails对象: SecurityContextHolder.getContext().getAuthentication().getPrincipal() 我知道在没有特殊配置的情况下,该调用将返回一个字符串,而不是使用自定义UserDetailsService实现创建的UserDetails对象,但我不希望总是到处检查“if(principal instanceof string)”。有没有一种方法可以通过

我正在尝试找出如何让Spring Security为此调用为匿名用户返回UserDetails对象:

SecurityContextHolder.getContext().getAuthentication().getPrincipal()
我知道在没有特殊配置的情况下,该调用将返回一个字符串,而不是使用自定义UserDetailsService实现创建的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) {
这是我的spring安全上下文(除了封闭的beans节点外,其余都是完整的)。您可以注意到,我尝试启用“匿名”



基于您在此处看到的代码的任何其他建议都是受欢迎的。

对于匿名用户,您还没有给出从
UserDetails
中提取哪些数据的详细信息。如果只想检查用户名,可以使用
Authentication.getName()

在任何情况下,如果需要更详细地访问安全上下文,最好使用自定义接口将应用程序代码与Spring安全类解耦(请参阅)。这样,您应该只在一个位置检查主体的类型,而不是重复您想要访问用户数据的“无处不在”检查


如果绝对希望在身份验证对象中始终具有相同的主体类型,而不管用户是否匿名,则必须禁用通过命名空间进行的匿名身份验证,并根据现有的
AnonymousAuthenticationFilter
添加自定义筛选器来执行此任务

你能解释一下你想用匿名
UserDetails
做什么吗?它将包含哪些数据?您将如何使用它?您不需要
,因为这是默认设置。您应该会看到调试日志中报告的
匿名AuthenticationFilter
作为确认。我试图避免“getPrincipal()”调用返回字符串。我希望该调用只返回UserDetails实现,无论是spring匿名身份验证还是用户登录。我希望避免必须为instanceof String测试“getPrincipal()”的返回值。当然,由于文档在某些领域非常模糊,并且特定配置点的信息在许多章节中都很分散,因此很难确定这是否是您应该做的事情,或者只是处理比较的实例。如果我不必按照你说的做,那么我一定是误解了一些非常基本的东西,因为方法安全性不适用于默认的匿名身份验证。您可以从我的代码中看到,我启用了全局方法安全性,但我可以在不登录的情况下请求调用“newSetup”方法的URL,而且我很确定我没有指定匿名用户应该具有角色\ u ADMIN的任何位置(如果我现在想的话,我不知道如何)。我将按照您的建议实现安全访问器facade。您问题的第二部分不清楚它与匿名身份验证或访问安全上下文的需要有何关系。annotation对非匿名用户有效吗?如果不是,则可能是应用程序上下文可见性问题-请参阅。还讨论了对MVC控制器使用安全注释的问题。不必担心预授权问题。事实证明,它与匿名登录无关,而与Spring应用程序上下文层次结构voodoo有关。这个问题的确切描述和解决方案是……是的,卢克——你完全正确。感谢您的提示,让我找到了常见问题解答和解决方案。
<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>