我是spring安全框架的新手。我只是在编译使用spring安全注释或spring安全框架添加安全特性的各种方法。
到目前为止发现了以下内容。
- 整页授权示例:
<intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />
-
页面内授权
示例:
<security:authorize access="hasRole('ROLE_ADMIN')">
-
方法级授权-
@PreAuthorize,@PostAuthorize,@PreFilter,@PostFilter
我不确定这是否是一个详尽的列表,以确保申请。同样需要一些帮助。谢谢
此外,我正在寻找可以轻松实现和配置的安全功能,在这些功能中,开发人员不太可能犯错误,同时实现所需的安全目标。看起来注释很容易使用,而且不太含糊。注释是否仅用于方法级别的授权?spring安全性是否提供可用于保护应用程序其他部分的注释?这些注释是否可以通过参数来配置权限或特权?
我希望我的问题不要太宽泛。如有任何修改或有益的意见,我们将不胜感激。
也许您需要从确定域模型的需求开始,什么是敏感数据,什么不是敏感数据,以及如何访问这些数据(HTML/JSP与REST/JSON与直接Java调用)。然后根据需要使用授权功能。您的列表几乎包含了大多数应用程序所需的内容,但要获得更精细、更高级的授权机制,请查看Spring的ACL:
http://docs.spring.io/spring-security/site/docs/3.0.x/reference/domain-acls.html
您可能想自己回答的另一个重要问题是,哪个应用程序层将负责实施您的安全性:MVC/REST与服务(将这种问题分散到多个层通常是个坏主意)。这将直接决定您将要选择的SS功能。
您可能希望在密切反映您特定领域的SS注释之上构建自己的注释。这样,所有的复杂性都将集中在一个地方,从而减少出错的空间。
例如,可以创建自定义注释(如@AuthorizedFor
),在其中可以添加各种特定于域的参数。然后,您可以使用一个SS注释来注释该注释,比如@Pre/PostAuthorize("hasAnyRole()")
(在这里,您还可以使用Spring的原生EL来进一步自定义行为),并使用Pre/PostInvocationAuthorizationAdvice
的自定义实现,在那里您可以根据自定义注释参数做出授权决定。这里的额外优势是,您将能够使用自定义注释来保护完整的类,而不必注释该类中的所有方法。在您的实现中,您可以获得MethodInvocation
实例,从中可以询问包含该方法的类,并查看其是否已注释,然后继续操作,就像方法本身已注释一样。
有关更深入的讨论,请参阅本文:http://blog.novoj.net/2012/03/27/combining-custom-annotations-for-securing-methods-with-spring-security/
实现spring安全性基本上有两种方法。通过.xml文件中的bean配置和其他使用Annotations。基于注释的方法很容易长期使用,因为它不太含糊。
这是对spring.io的引用。这两种方法都解释得很好。
http://spring.io/blog/2013/07/03/spring-security-java-config-preview-web-security/
注释是纯基于java的配置,很可能会超过xml配置。
列表中的三个项目有不同的用途:
-
intercept-url:在servlet层添加安全性。换句话说,你可以控制谁可以/不能访问你的应用程序中的任何url。例如,您可以仅向管理员添加访问url
/admin/some_critical_operation
的权限,但允许所有经过身份验证的用户访问/some_informational_page
。仅凭这种授权就可以保护您的应用程序,但这是一种非常脆弱的设计。添加或更改url很容易在没有通知的情况下破坏安全。 -
在页面授权:这不是真正的授权,只是一个方便的标签,用于隐藏不适合当前用户的html内容。例如,非管理员用户不应该看到按钮
create new user
。正如我所说,这不是真正的安全措施,因为如果没有应用任何其他授权类型,用户可以在浏览器中键入url并获得访问权限。 -
方法级授权:为服务层添加安全性。这意味着您可以对谁可以/不能调用某个服务类的方法施加限制。它被认为更安全,更难妥协,因为它在应用层堆栈中应用得更深。它既可以与注释一起应用,也可以与安全命名空间一起应用。
通常,您首先要在服务层保护您的应用程序,然后添加一些url控件。在页面中添加授权标签是可选的。
我还不能发表评论,但关于你的问题:
是否有可配置的注释?例如,我提供了方法级安全注释,您可以在其中提供参数,比如有权访问方法或访问方法返回的元素的用户的角色
您可以自由地编写自己的注释,这些注释又使用本机Spring Security注释进行注释。这使得它们本质上是一个特定于域的扩展。也就是说,标准的SS注释允许使用SpEL,它相当灵活,甚至很难与您的特定域绑定。您可以很容易地断言用户是否具有某些角色(GrantedAuthority)等。。。
如果您想实现自己的注释,请参阅我的另一个答案中的链接以进行彻底的讨论。
我可以给你举一个我最近参与的一个项目的具体例子。我们有由外部系统管理的授权组,还有定义对某些资源的访问的内置逻辑。因此,基本上我们有两个地方可以查找授权参数。我们已经创建了授权组(通过LDAP从外部检索)和授权角色(内置的业务逻辑)的概念。这些组很简单——如果用户是该组的成员,则授予他们访问权限,否则拒绝访问。对于角色,我们有业务规则来确定用户是否具有特定角色(例如,已签署的T&C、已接受的EULA等)。所有这些都是在身份验证阶段确定的。
为了更容易解释我们的访问控制,我们创建了两个注释@AuthorisedForGroups({group1, group2, ...})
和@AuthorisedForRoles({role1, role2,...})
。每一个都用Spring的原生@PreAuthorize("hasAnyRole()")
进行了注释。注意"hasAnyRole()"的使用——这只是告诉Spring"让所有通过身份验证的人都进来","我们将自己做出授权决定"。然后在PreInvocationAuthorizationAdvice
的自定义实现中做出授权决策(事实上,我们只是扩展了Spring自己的实现ExpressionBasedPreInvocationAdvice
),并将决策逻辑放入#before()
方法中:
@Override
public boolean before(Authentication authentication, MethodInvocation mi, PreInvocationAttribute attr) {
// 1) get AuthorisedForGroups & AuthorisedForRoles for the method
// 2) if either is missing from the method, check the enclosing class
// 3) if no annotations found - simply return super.before(...)
// 4) else, introspect the 'authentication' and see if it has the required groups/roles
// - here you may want to use 'ExpressionBasedAnnotationAttributeFactory' to
// create your own expressions which you then pass to super.before(...).
// This especially makes sense when your groups/roles
// are mapped to GrantedAuthority instances - as it was the case with our code.
}
希望这能有所帮助。