Spring Security — это инфраструктура безопасности, которая может предоставлять решения для декларативного контроля доступа к безопасности для систем корпоративных приложений на основе Spring. Он предоставляет набор bean-компонентов, которые можно настроить в контексте приложения Spring, в полной мере используя функции Spring IoC, DI (инверсия управления, DI: внедрение зависимостей) и AOP (аспектно-ориентированное программирование) для предоставления прикладным системам декларативного безопасного доступа. возможности управления уменьшают усилия по написанию большого количества повторяющегося кода для средств управления безопасностью корпоративной системы.
предисловие
spring security 3.0
уже доступноspring el
Выражения для управления авторизацией, позволяющие использовать сложную логическую логику в выражениях для управления правами доступа.
общие выражения
Базовым классом для доступных объектов выражений Spring Security является SecurityExpressionRoot.
выражение | описывать |
---|---|
hasRole([role] ) |
Возвращает true, если у пользователя есть указанная роль (Spring security По умолчанию он будет иметьROLE_ префикс), удалить ссылкиRemove the ROLE_
|
hasAnyRole([role1,role2]) |
Возвращает true, если у пользователя есть какая-либо из указанных ролей |
hasAuthority([authority]) |
ЭквивалентноhasRole , но не сROLE_ префикс |
hasAnyAuthority([auth1,auth2]) |
ЭквивалентноhasAnyRole
|
permitAll |
всегда возвращает истину |
denyAll |
всегда возвращает ложь |
anonymous |
Текущий пользовательanonymous возвращает истину, когда |
rememberMe |
Нынешний воинrememberMe пользователь возвращает истину |
authentication |
текущий авторизованный пользовательauthentication объект |
fullAuthenticated |
Текущий пользователь неanonymous ни одинrememberMe Возвращает true, когда пользователь |
hasIpAddress('192.168.1.0/24')) |
Возвращает true, если IP-адрес, отправленный запросом, совпадает |
Часть кода:
......
private String defaultRolePrefix = "ROLE_"; //ROLE_前缀
/** Allows "permitAll" expression */
public final boolean permitAll = true; //全部true
/** Allows "denyAll" expression */
public final boolean denyAll = false; //全部false
public final boolean permitAll() {
return true;
}
public final boolean denyAll() {
return false;
}
public final boolean isAnonymous() {
//是否是anonymous
return trustResolver.isAnonymous(authentication);
}
public final boolean isRememberMe() {
//是否是rememberme
return trustResolver.isRememberMe(authentication);
}
......
Безопасные выражения URL
onfig.antMatchers("/person/*").access("hasRole('ADMIN') or hasRole('USER')")
.anyRequest().authenticated();
Здесь мы определяем приложение/person/*
Диапазон URL-адресов, предназначенных только для владельцевADMIN
илиUSER
Разрешения действительны для пользователей.
Ссылки на bean-компоненты в безопасных веб-выражениях
config.antMatchers("/person/*").access("hasRole('ADMIN') or hasRole('USER')")
.antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)")
.anyRequest()
.access("@rbacService.hasPermission(request,authentication)");
RbacServiceImpl
@Component("rbacService")
@Slf4j
public class RbacServiceImpl implements RbacService {
/**
* uri匹配工具
*/
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
log.info("【RbacServiceImpl】 --hasPermission={}", authentication.getPrincipal());
Object principal = authentication.getPrincipal();
boolean hasPermission = false;
//有可能是匿名的anonymous
if (principal instanceof SysUser) {
//admin永远放回true
if (StringUtils.equals("admin", ((SysUser) principal).getUsername())) {
hasPermission = true;
} else {
//读取用户所拥有权限所有的URL 在这里全部返回true
Set<String> urls = new HashSet<>();
for (String url : urls) {
if (antPathMatcher.match(url, request.getRequestURI())) {
hasPermission = true;
break;
}
}
}
}
return hasPermission;
}
public boolean checkUserId(Authentication authentication, int id) {
return true;
}
}
Эффект следующий:
Безопасное выражение метода
Контроль доступа на уровне метода более сложен.Spring Security
Предоставляются четыре аннотации, а именно@PreAuthorize
, @PreFilter
, @PostAuthorize
а также@PostFilter
Аннотировать методом
- Включить настройку аннотаций на уровне метода
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MerryyouSecurityConfig extends WebSecurityConfigurerAdapter {
- Настройте соответствующий bean-компонент
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@ConditionalOnMissingBean(PasswordEncoder.class)
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
- Используйте аннотации к методам
/**
* 查询所有人员
*/
@PreAuthorize("hasRole('ADMIN')")
@ApiOperation(value = "获得person列表", notes = "")
@GetMapping(value = "/persons")
public List<Person> getPersons() {
return personService.findAll();
}
PreAuthorize
Аннотация @PreAuthorize подходит для проверки авторизации перед входом в метод
@PreAuthorize("hasRole('ADMIN')")
List<Person> findAll();
PostAuthorize
@PostAuthorize выполняет проверку авторизации после выполнения метода, что подходит для проверки авторизации с возвращаемым значением.Spring EL
Предоставляет возвращаемый объект, чтобы иметь возможность получить возвращенный объект на языке выражений.returnObject
.
@PostAuthorize("returnObject.name == authentication.name")
Person findOne(Integer id);
Предварительная авторизация фильтров по параметрам
//当有多个对象是使用filterTarget进行标注
@PreFilter(filterTarget="ids", value="filterObject%2==0")
public void delete(List<Integer> ids, List<String> usernames) {
...
}
PostFilter фильтрует возвращаемые результаты
@PreAuthorize("hasRole('ADMIN')")
@PostFilter("filterObject.name == authentication.name")
List<Person> findAll();
Эффект следующий:
загрузка кода
Скачать с моего гитхаба,GitHub.com/Longfeizhen…