我正在开发一个具有spring security的应用程序。我要求在创建用户时为其分配默认密码。用户必须重置密码才能完全访问其模块。因此,登录后他将无法访问任何资源,直到他更改密码。
我的数据库中有一个状态标志,用于跟踪用户是否是新用户。 我还有一个使用自定义JdbcDaoImpl
的自定义身份验证提供程序有关这样做的任何线索吗?
答案 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
课程中包含setConfig
,setPassword
和setName
方法,并且网络服务会调用{{} 1}}调用setConfig
和setPassword
然后这不起作用,因为方面不适用于类中的方法调用。
在这种情况下,您可能希望编写自己的方面来检查传递给方法的实际参数(这自然很脆弱,如果可以的话,请避免使用它)。或者在最坏的情况下,您可以检查setName方法本身的安全性(安全性是一个跨领域的问题,理想情况下不应该包含在执行其他操作的方法中,这会降低内聚力,因为方法现在有两个职责)。
如果您确实推出了自己的拦截器,那么您需要查看setName
类,该类为您提供当前线程的SecurityContext
对象(例如请求)。
您还需要修改Authentication
实现,以便在为用户提供适当设置角色时(基于数据库标记的ROLE_USER或ROLE_NEW_USER)。
最后但并非最不重要的是,您需要弄清楚您的应用程序如何处理身份验证失败。在Web服务示例中,如果用户身份验证失败,您可以将用户重定向到更改密码页面。当然,如果它们是ROLE_NEW_USER,则将它们重定向到更改密码页面可能会变得棘手,如果它们没有角色,则将它们重定向到注册页面。
答案 1 :(得分:1)
您可能希望根据以下情况重新审视您的要求:
管理员使用默认密码为Fred创建帐户。
弗雷德,有些不感兴趣,几天都没有尝试登录。
与此同时,Jim知道(或已经猜到)Fred有一个新帐户,使用默认密码登录Fred,重置它,现在可以做假装成Fred的事情......直到Fred终于尝试使用他的帐户,但由于他不知道密码而失败。
您不应使用默认密码。至少你应该为每个新用户生成一个随机密码,并通过一些(相对)安全的方式将其传达给用户。