Spring Security 3自定义身份验证要求....需要帮助!

时间:2011-06-19 11:06:21

标签: java authentication spring-security

我正在开发一个具有spring security的应用程序。我要求在创建用户时为其分配默认密码。用户必须重置密码才能完全访问其模块。因此,登录后他将无法访问任何资源,直到他更改密码。

我的数据库中有一个状态标志,用于跟踪用户是否是新用户。 我还有一个使用自定义JdbcDaoImpl

的自定义身份验证提供程序

有关这样做的任何线索吗?

2 个答案:

答案 0 :(得分:4)

听起来你有两个不同的角色,ROLE_USER和ROLE_NEW_USER。诀窍是配置拦截器以指定您想要的角色。拦截器的工作是识别您想要保护的资源以及访问它们所需的角色。

您没有指定,因此我们假设您正在构建Web应用程序。默认情况下,您可能有某种FilterSecurityInterceptor。配置可能看起来像......

       

这表示对所有网址的访问都是安全的,需要ROLE_USER。如果您的Web应用程序碰巧有与此用例匹配的URL,您可能会执行类似......

的操作

            

当然,如果您的Web应用程序结构不是那么开心,那么事情就会变得棘手。例如,可能允许访问/updateConfig?newpassword=foobar,以便用户可以更改其密码,但不允许访问/updateConfig?username=newname

在这种情况下,您将不得不将拦截器放置在较低级别。也许您可以使用MethodSecurityInterceptor对配置服务进行访问,以便setPassword方法具有ROLE_NEW_USER,setName方法具有ROLE_USER。请记住,MethodSecurityInterceptor是一个方面,因此,如果您的ConfigService课程中包含setConfigsetPasswordsetName方法,并且网络服务会调用{{} 1}}调用setConfigsetPassword然后这不起作用,因为方面不适用于类中的方法调用。

在这种情况下,您可能希望编写自己的方面来检查传递给方法的实际参数(这自然很脆弱,如果可以的话,请避免使用它)。或者在最坏的情况下,您可以检查setName方法本身的安全性(安全性是一个跨领域的问题,理想情况下不应该包含在执行其他操作的方法中,这会降低内聚力,因为方法现在有两个职责)。

如果您确实推出了自己的拦截器,那么您需要查看setName类,该类为您提供当前线程的SecurityContext对象(例如请求)。

您还需要修改Authentication实现,以便在为用户提供适当设置角色时(基于数据库标记的ROLE_USER或ROLE_NEW_USER)。

最后但并非最不重要的是,您需要弄清楚您的应用程序如何处理身份验证失败。在Web服务示例中,如果用户身份验证失败,您可以将用户重定向到更改密码页面。当然,如果它们是ROLE_NEW_USER,则将它们重定向到更改密码页面可能会变得棘手,如果它们没有角色,则将它们重定向到注册页面。

答案 1 :(得分:1)

您可能希望根据以下情况重新审视您的要求:

  • 管理员使用默认密码为Fred创建帐户。

  • 弗雷德,有些不感兴趣,几天都没有尝试登录。

  • 与此同时,Jim知道(或已经猜到)Fred有一个新帐户,使用默认密码登录Fred,重置它,现在可以做假装成Fred的事情......直到Fred终于尝试使用他的帐户,但由于他不知道密码而失败。

您不应使用默认密码。至少你应该为每个新用户生成一个随机密码,并通过一些(相对)安全的方式将其传达给用户。