问题描述
我一直在寻找有关如何在使用 Spring数据存储库来访问数据库,从而查询注册用户.
I was looking for a concrete, serious and complete example on how to use Spring security in a Spring Boot application that uses Spring data repositories to access the database and therefore to query about registered users.
我已经看到,通过覆盖configure
方法,例如使用以下选项,它可以使用Spring安全性轻松保护一系列网页:
I've seen that it's easily protected a range of webpages using Spring security by overriding the configure
method, for example with the following options:
http.authorizeRequests()
.antMatchers("/", "/css/**", "/js/**", "/vendor/**", "/templates/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
例如,此代码保护用户免于访问http://localhost:3000/home/users/
,但随后允许访问http://localhost:3000/login
或仅访问http://localhost:3000
.
This code protects users for example from accessing http://localhost:3000/home/users/
, but allows then to access http://localhost:3000/login
or simply http://localhost:3000
.
我一直在阅读有关Spring安全性的内容,但是我无法获得如何保护应用程序不同部分的方法,例如,当用户登录到网站并禁止他从示例中访问时http://localhost:3000/home/users/another_user
,通常用于控制登录用户对网站所有部分的访问.
I've been reading around about Spring security, but I can't get how can I protect the different parts of an application, for example, when a user has logged in to the website, and prohibit him from accessing from example http://localhost:3000/home/users/another_user
, and in general to control the access of a logged user to all parts of the website.
我正在使用 Spring数据存储库,用于通过实体操纵数据库的数据.
I'm using Spring data repositories to manipulate data of the database through the entities.
您是否知道一个示例,该示例结合使用Spring安全性和Spring存储库(必要时还使用其他工具)来保护(并验证)网站的不同部分? (视频教程)也可能有用.
Do you know about an example that uses Spring security in conjunction with Spring repositories (and if necessary other tools) to protect (and authenticate) different parts of a website? A (video-)tutorial may also be useful.
感谢您的帮助.
注意:我已经看过sagan网站的存储库,但是要了解正在发生的事情却很复杂...
Note: I've looked at the sagan website's repository, but it's quite complex to understand what's going on...
推荐答案
如上所述,ACL是一种选择,但是另一种可能更简单的解决方案可能是在方法级别应用安全性.
As noted above ACLs are one option however an alternative and possibly simpler solution may to be to apply security at the method level.
请参阅第15.3节.
https://docs. spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
因此,假设您有一个URL/users/123,其中123是当前用户,并且委派了服务层方法来加载用户,那么我如何防止用户篡改URL并看到例如返回的数据./users/456.
So supposing you have an URL /users/123 where 123 is the current user and which delegates to a service layer method to load the user then how do I prevent the user from tampering with the URL and seeing data returned by e.g. /users/456.
一种方法是通过@PostAuthorize批注应用方法级别的安全性:
One approach is to apply method level security via the @PostAuthorize annotation:
@PostAuthorize("hasPermission(returnObject, null)")
public User findById(Long id) {
return repository.findOne(id);
}
安全检查委托给org.springframework.security.access.PermissionEvaluator的实现
The security checks are delegated to an implementation of org.springframework.security.access.PermissionEvaluator
一个实现可能如下所示:
An implementation could look like the below:
public class BasePermissionsEvaluator implements PermissionEvaluator {
public boolean hasPermission(Authentication authentication, Object domainObject) {
return hasPermission(authentication, domainObject, null);
}
@Override
public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
boolean hasPermission = true;
//User is my custom class representing a logged in user
//UserEntity is my custom interface implemented by entities associated with specific user
//If user is an Admin allow access
//Otherwise allow access if logged in user 'owns' the DomainObject instance
User user = (User) authentication.getPrincipal();
if(! user.isAdmin()){
if (domainObject instanceof UserEntity) {
User owner = ((UserEntity) domainObject).getOwner();
hasPermission = user.equals(owner);
}
}
return hasPermission;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return false;
}
}
PermissionEvaluator的配置类似于XML中的以下内容,因此您需要转换为Java配置:
Configuration of the PermissionEvaluator looks like the following in XML so you would need to convert to Java config:
<security:global-method-security
pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator" ref="permissionEvaluator" />
</bean>
<bean id="permissionEvaluator" class="com.mycompany.BasePermissionsEvaluator" />
以下概述了将XML配置转换为Java配置的方法:
The following outlines converting the XML config to Java config:
因此,在您现有的安全配置类中,您似乎应该添加:
So in your existing security configuration class it looks like you would add:
@EnableGlobalMethodSecurity(prePostEnabled=true) //ADD THIS
public class MySecurityConfig{
@Override
protected MethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
//SET TO OUR CUSTOM PERMISSIONS HANDLER DETAILED ABOVE
expressionHandler.setPermissionEvaluator(new BasePermissionsEvaluator());
return expressionHandler;
}
}
这篇关于将Spring Security与Spring存储库结合使用,以保护和认证网站的各个部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!