spring-shiro 基本使用

maven配置

<!-- shiro-web -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-web</artifactId>  
        <version>${shiro-version}</version>  
    </dependency>  
    <!-- shiro-spring -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-spring</artifactId>  
        <version>${shiro-version}</version>  
    </dependency>  
    <!-- shiro-ehcache -->  
    <dependency>  
        <groupId>org.apache.shiro</groupId>  
        <artifactId>shiro-ehcache</artifactId>  
        <version>${shiro-version}</version>  
    </dependency>  
    ...
    <properties>
        <shiro-version>1.2.4</shiro-version>
    </properties>

spring配置

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>    
 
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" 
    depends-on="lifecycleBeanPostProcessor"/>  

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
<!-- securityManager 核心控制器 -->
    <property name="realm" ref="DefaultRealm"/>  
</bean>  

  <!-- 过滤器配置, 同时在web.xml中配置filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
    <property name="securityManager" ref="securityManager"/>  
    <property name="loginUrl" value="/account/to_login.do"/>  
    <property name="successUrl" value="/success.jsp"/>
    <property name="unauthorizedUrl" value="/noperm.jsp"/>
    <property name="filters">
        <map>
            <entry key="authc">
                <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" />
            </entry>
        </map>
    </property>  
    <property name="filterChainDefinitions">  
        <value>  
            /logout.do        = anon    <!--anon:anonymous, 匿名的, 不需要权限 -->
            /image/*.do        = authc    <!-- 需要认证通过, 即登录成功 -->
            /blog/**.do        = authc,perms[blog] <!-- 需要名称为blog的权限permission-->
            /admin/*.do        = authc,roles[admin] <!-- 需要名称为admin的角色role-->
            <!-- 说明: /*匹配的的是/abc;  /** 匹配的是多个/*, 比如/abc/def -->
        </value>  
    </property>  
</bean>

web.xml

<filter>  
    <filter-name>shiroFilter</filter-name>  
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    <init-param>  
        <param-name>targetFilterLifecycle</param-name>  
        <param-value>true</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>shiroFilter</filter-name>  
    <url-pattern>*.do</url-pattern>  
</filter-mapping>    

<!-- sitemesh -->
<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:app-servlet.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

PS : shiro filter,放在mvc的filter/servlet前面,如果有sitemesh,放在sitemesh前面

Realm类

/**
 * 登录和检查授权的时候调用当前类
 */
@Component("DefaultRealm")
public class DefaultRealm extends AuthorizingRealm {

  @Resource
  private AdminDao adminDao;

  public DefaultRealm() {
    setName("DefaultRealm");// This name must match the name in the User  
  }

  //获取授权信息, 用于验证权限
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    String username = (String) principalCollection.getPrimaryPrincipal();
    AdminUser admin = adminDao.getUniqueByProperty("username", username);
    Set<Role> roleSet = admin.getRoles();
    if (roleSet != null) {
      //获取角色权限
      Set<String> roles = new HashSet<>();
      Set<String> stringPermissions = new HashSet<>();
      for (Role role : roleSet) {
        roles.add(role.getRoleName());

        //封装到验证信息
        Set<Permission> permissions = role.getPermissions();
        for (Permission permission : permissions) {
          stringPermissions.add(permission.getPermissionName());
        }
      }
      
      SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();  
      authorizationInfo.setRoles(roles);  
      authorizationInfo.setStringPermissions(stringPermissions);  
      return authorizationInfo;
    }
    return null;
  }

  //获取验证信息,用于登录验证用户名密码
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken principals)
      throws AuthenticationException {
    String username = (String) principals.getPrincipal();
    if (StringUtils.isNotEmpty(username)) {
      AdminUser admin = adminDao.getUniqueByProperty("username", username);
      SimpleAccount account = new SimpleAccount(username, admin.getPassword(), getName());
      return account;
    }
    return null;
  }

}

MVC登录验证

//在MVC的Controller中, 接收参数username和password, 装配成UsernamePasswordToken对象,
//然后用subject对象login方法进行登录.
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
subject.login(token);

User-Role-Permission实体类

@Entity
public class User {
    private String username; 
    private String password="";
    //省略getter setter
    
    private Set<Role> roles;
    
    @ManyToMany(targetEntity=Role.class)
    public Set<Role> getRoles() {
      return roles;
    }

    public void setRoles(Set<Role> roles) {
      this.roles = roles;
    }
}

@Entity
public class Role{
  private String roleName;    //省略getter setter
  private Set<Permission> permissions = new HashSet<>();
  
  @ManyToMany
  public Set<Permission> getPermissions() {
    return permissions;
  }

  public void setPermissions(Set<Permission> permissions) {
    this.permissions = permissions;
  }
}  

@Entity
public class Permission {
    private String permissionName;//省略getter setter
}

相关推荐