apache shiro 基本架构
Subject:当前登录人的一个安全视图。代码可以从对象中获取登录信息。
SecurityManager:架构的核心,组织管理所有的Subject。
Realms:用户自定义,提供获取用户信息,认证信息。
下面是更加详细的架构图:
apache shiro 与Spring boot集成
spring boot starter
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.1</version>
</dependency>
通过configuration配置shiro。
@Configuration
public class ShiroConfig {
@Bean
public SecurityManager securityManager() {
return new DefaultWebSecurityManager();
}
@Bean
public ShiroSecurityRealm myRealm() {
return new ShiroSecurityRealm();
}
/**
* 配置ShiroFilterFactoryBean
*
* @param securityManager
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
System.out.println("执行 ShiroFilterFactoryBean shiroFilter");
ShiroFilterFactoryBean shiroFilterFactoryBean = new
ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/public/login");
shiroFilterFactoryBean.setSuccessUrl("/");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/public/**", "anon");
filterChainDefinitionMap.put("/authc/**", "authc");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public AuthorizationAttributeSourceAdvisor
authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
= new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
注解
Spring中,在Controller上添加RequiresPermissions,RequiresRoles注解,从而为接口添加访问权限限制。
权限校验:
@RequiresPermissions("account:create")
public void openAccount( Account acct ) {
//create the account
}
角色校验:
@RequiresRoles( "teller" )
public void openAccount( Account acct ) {
//do something in here that only a teller //should do
}
shiro 配置
shiro有默认的实现,能够读取ini配置。本文没有采用这种方式,而是直接在configuration中配置。
# =======================
# Shiro INI configuration
# =======================
[main]
# Objects and their properties are defined here,
# Such as the securityManager, Realms and anything
# else needed to build the SecurityManager
[users]
# The 'users' section is for simple deployments
# when you only need a small number of statically-defined
# set of User accounts.
[roles]
# The 'roles' section is for simple deployments
# when you only need a small number of statically-defined
# roles.
[urls]
# The 'urls' section is used for url-based security
# in web applications. We'll discuss this section in the
# Web documentation
main中配置realms以及SecurityManager。
urls中配置路径、文件的权限。
默认Filter
Filter Name | 类 | 描述 |
---|---|---|
anon | org.apache.shiro.web.filter.authc.AnonymousFilter | 需要登录,但不做权限校验。 |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter | 基于表单的验证。对于访问进行权限校验。如果不通过则redirect到loginurl。 |
authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter | 需要用户登录才能继续访问资源。如果用户没有登录,则通过要求用户通过基本的HTTP协议进行登录。登录完成后,会继续访问之前的url。 |
logout | org.apache.shiro.web.filter.authc.LogoutFilter | 接到这个请求,会直接logout当前的subject,并重定向到配置的 redirectRUL。 |
noSessionCreation | org.apache.shiro.web.filter.session.NoSessionCreationFilter | 这是一个非常有用的过滤器,可以放在任何过滤器链的前面,这些过滤器链可能会导致REST、SOAP或其他不打算参与会话的服务调用。 |
perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter | 如果当前用户具有由映射值指定的权限,则允许访问;如果用户没有指定的所有权限,则拒绝访问。 |
port | org.apache.shiro.web.filter.authz.PortFilter | 要求请求位于特定端口上的筛选器,如果不是,则重定向到该端口上的相同URL。 |
rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter | HTTP的method(GET,POST等)转成rest的方法(read,create等)。 |
roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter | 根据角色过滤 |
ssl | org.apache.shiro.web.filter.authz.SslFilter | https |
user | org.apache.shiro.web.filter.authc.UserFilter | 用户已经登录,或者设置了remember me。判断条件: subject.getPrincipal() != null. |
anon
用户需要登录才能访问此资源,但是不会做权限校验。
用例:
[urls]
/user/signup/** = anon
/user/** = authc>
user/signup路径下所有的资源登录后都可以访问,但是/user/目录下其他的资源,都需要做权限校验。
noSessionCreation
执行过程:
如果一个Subject还没有session,那么将会禁止对于subject.getSession() 和subject.getSession(true)的调用。如果在期间有调用,则抛出异常。
如果在filter调用之前Subject已经有Session了,或者在应用的其他地方创建了session,或者在此filter之前的filter创建了session,对于此filter没有影响。
rest
http method 和rest 原语的映射规则。