zoukankan      html  css  js  c++  java
  • SpringMVC集成shrio框架

    使用SHIRO的步骤:
    1,导入jar
    2,配置web.xml
    3,建立dbRelm
    4,在Spring中配置

    添加所需jar包:

    1. <!--Apache Shiro所需的jar包-->    
    2.     <dependency>    
    3.       <groupId>org.apache.shiro</groupId>    
    4.       <artifactId>shiro-core</artifactId>    
    5.       <version>1.2.2</version>    
    6.     </dependency>    
    7.     <dependency>    
    8.       <groupId>org.apache.shiro</groupId>    
    9.       <artifactId>shiro-web</artifactId>    
    10.       <version>1.2.2</version>    
    11.     </dependency>    
    12.     <dependency>    
    13.       <groupId>org.apache.shiro</groupId>    
    14.       <artifactId>shiro-spring</artifactId>    
    15.       <version>1.2.2</version>    
    16.     </dependency>   
    17.   </dependencies>  

    web.xml中配置shrio的过滤器:

    1. <!-- Shiro配置 -->    
    2.   <filter>    
    3.     <filter-name>shiroFilter</filter-name>    
    4.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    
    5.   </filter>    
    6.   <filter-mapping>    
    7.     <filter-name>shiroFilter</filter-name>    
    8.     <url-pattern>/*</url-pattern>    
    9.   </filter-mapping>  

    权限控制类:

    public class ShiroRealm extends AuthorizingRealm {


    private static final Logger log = Logger.getLogger(ShiroRealm.class);

    @Autowired
    private SysUsersService userService;
    @Autowired
    private SysUserRolesService userRoleService;
    @Autowired
    private SysRolePermissionsService sysRolePermissionsService;
    @Autowired
    private SysPermissionsService sysPermissionsService;

    /**
    * 为当前登录的Subject授予角色和权限
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {


    // 获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()
    String currentUsername = (String) super.getAvailablePrincipal(principals);
    List<String> roleList = new ArrayList<String>();
    List<String> permissionList = new ArrayList<String>();
    // 从数据库中获取当前登录用户的详细信息
    // roleList.add("admin");

    SysUsers user = userService.getUserByUsername(currentUsername);
    if(null != user){
    //超级用户直接获取所有权限
    if(user.getIsAdministrator()==1){
    List<SysPermissions> pList = sysPermissionsService.getAll();
    if(pList!=null && pList.size()>0){
    for (SysPermissions p: pList) {
    permissionList.add(p.getPermissionKey());
    }
    }
    }else {
    //获取用户角色列表
    List<SysUserRoles> roles = userRoleService.getUserRolesByUserName(currentUsername);
    List<Integer> roleIdList = new ArrayList<>();
    if (roles != null&&roles.size()>0) {
    for (SysUserRoles role : roles) {
    System.out.println(role.getRoleKey());
    log.debug("授予角色>>>" + role.getRoleKey());
    roleList.add(role.getRoleKey());
    roleIdList.add(role.getRoleId());
    }
    }
    //获取用户权限列表
    List<SysRolePermissions> permissionsList = sysRolePermissionsService.getPermissionsByRoleIds(roleIdList);
    if (permissionsList != null && permissionsList.size() > 0) {
    for (SysRolePermissions pmss : permissionsList) {
    if (!StringUtils.isBlank(pmss.getPermissionKey())) {
    log.debug("授予权限>>>>" + pmss.getPermissionKey());
    permissionList.add(pmss.getPermissionKey());
    }
    }
    }
    }

    }else {
    throw new AuthorizationException();
    }

    // if (null != user) {
    // // 实体类User中包含有用户角色的实体类信息
    // if (null != user.getRoles() && user.getRoles().size() > 0) {
    // // 获取当前登录用户的角色
    // for (Role role : user.getRoles()) {
    // if (!StringUtils.isBlank(role.getName())) {
    // log.debug("授予角色>>>" + role.getName());
    // roleList.add(role.getName());
    // }
    // }
    // }
    // // 实体类User中包含有角色权限的实体类信息
    // if (null != user.getPermissions() && user.getPermissions().size() > 0) {
    // for (Permission pmss : user.getPermissions()) {
    // if (!StringUtils.isBlank(pmss.getPermission())) {
    // log.debug("授予权限>>>>" + pmss.getPermission());
    // permissionList.add(pmss.getPermission());
    // }
    // }
    // }
    // } else {
    // throw new AuthorizationException();
    // }
    // 为当前用户设置角色和权限
    SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
    simpleAuthorInfo.addRoles(roleList);
    simpleAuthorInfo.addStringPermissions(permissionList);


    return simpleAuthorInfo;
    }


    /**
    * 验证当前登录的Subject
    * 认证回调函数,登录时调用.
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
    throws AuthenticationException {
    // 获取基于用户名和密码的令牌
    UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

    SysUsers user = userService.getUserByUsername(token.getUsername());

    AuthenticationInfo authcInfo = null;
    if (user == null) {
    throw new UnknownAccountException();// 未知账户
    }
    else if(!user.getPassword().equals(ParseMD5.parseStrToMd5L32(String.valueOf(token.getPassword())))){
    throw new UnknownAccountException();// 账户密码错误,与管理员联系
    }
    else if (user.getStatus() == 0) {
    throw new LockedAccountException();// 账户已锁定,与管理员联系
    }
    else {
    authcInfo = new SimpleAuthenticationInfo(user.getUsername(),
    token.getPassword(),
    getName());

    this.setSession("currentUser", user.getUsername());
    }

    return authcInfo;
    }


    /**
    * 更新授权信息缓存
    */
    public void clearCachedAuthorizationInfo(String principal) {
    SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
    clearCachedAuthorizationInfo(principals);
    }

    /**
    * ShiroSession设置
    *
    * @see 使用时直接用HttpSession.getAttribute(key)就可以取到
    */
    private void setSession(Object key, Object value) {
    Subject currentUser = SecurityUtils.getSubject();
    if (null != currentUser) {
    Session session = currentUser.getSession();
    if (null != session) {
    session.setAttribute(key, value);
    }
    }
    }
    }


    在spring的配置文件中配置:新建spring-shrio.xml文件:

    1. <?xml version="1.0" encoding="UTF-8" ?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    4.        xmlns:aop="http://www.springframework.org/schema/aop"  
    5.        xmlns:tx="http://www.springframework.org/schema/tx"  
    6.        xmlns:context="http://www.springframework.org/schema/context"  
    7.        xsi:schemaLocation="  
    8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
    9. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd  
    10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
    11. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
    12.   
    13.     <!-- 配置权限管理器 -->  
    14.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">    
    15.         <!-- ref对应我们写的realm  MyShiro -->  
    16.         <property name="realm" ref="myShiro"/>    
    17.         <!-- 使用下面配置的缓存管理器 -->  
    18.         <property name="cacheManager" ref="cacheManager"/>    
    19.     </bean>  
    20.       
    21.     <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->  
    22.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">   
    23.         <!-- 调用我们配置的权限管理器 -->   
    24.         <property name="securityManager" ref="securityManager"/>   
    25.         <!-- 配置我们的登录请求地址 -->   
    26.         <property name="loginUrl" value="/login"/>    <!--login方法我们自定义一个控制器-->
    27.         <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->  
    28.         <property name="successUrl" value="/main"/>    
    29.         <!-- 如果您请求的资源不再您的权限范围,则跳转到/unauthorized请求地址 -->  
    30.         <property name="unauthorizedUrl" value="/unauthorized"/>    
    31.         <!-- 权限配置 -->  
    32.         <property name="filterChainDefinitions">    
    33.             <value>    
    34.                 <!-- anon表示此地址不需要任何权限即可访问 -->  
    35.                 /static/**=anon  
    36.                 <!-- perms[user:query]表示访问此连接需要权限为user:query的用户 -->  
    37.                 /user=perms[user:query]  
    38.                 <!-- roles[manager]表示访问此连接需要用户的角色为manager -->  
    39.                 /user/add=roles[manager]  
    40.                 /user/del/**=roles[admin]  
    41.                 /user/edit/**=roles[manager]  
    42.                 <!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login-->    
    43.                 /** = authc  
    44.             </value>    
    45.         </property>    
    46.     </bean>  
    47.       
    48.      <bean id="myShiro" class="ShrioRealm"/><!--权限控制类的全类名-->
    49.     <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />    
    50.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />   
    51.       
    52. </beans>  

    对于登录,未授权,错误的请求url写上请求控制处理方法:

    package net.lcheng.manage.controller;


    import net.lcheng.commons.utils.ParseMD5;
    import net.lcheng.manage.utils.ControllerUtils;
    import net.lcheng.manage.vo.PasswordModel;
    import net.lcheng.model.SysUsers;
    import net.lcheng.service.SysPermissionsService;
    import net.lcheng.service.SysUsersService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.subject.Subject;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    import javax.validation.Valid;

    @Controller
    public class HomeController {

    @Autowired
    private SysUsersService usersService;
    @Autowired
    private SysPermissionsService permissionsService;

    @RequestMapping("/main")
    // @RequiresRoles("admin")
    // @RequiresPermissions("user:create")
    public String main(Model model) throws Exception {
    ControllerUtils.common(model,permissionsService,"");
    return "main";
    }

    /**权限不足错误页面*/
    @RequestMapping("/unauthorized")
    public String unauthorized(Model model){
    Subject currentUser = SecurityUtils.getSubject();//获取当前用户
    if(currentUser.isAuthenticated()) {
    model.addAttribute("userName",currentUser.getPrincipals());
    }
    return "unauthorized";
    }

    /**错误页面*/
    @RequestMapping("/error")
    public String error(Model model){
    Subject currentUser = SecurityUtils.getSubject();//获取当前用户
    if(currentUser.isAuthenticated()) {
    model.addAttribute("userName",currentUser.getPrincipals());
    }
    return "error";
    }

    @RequestMapping(value = "/change_pwd",method = RequestMethod.GET)
    public String changePwd(Model model){
    model.addAttribute("PasswordModel",new PasswordModel());
    ControllerUtils.common(model,permissionsService,"");

    return "change_pwd";
    }
    @RequestMapping(value = "/change_pwd",method = RequestMethod.POST)
    public String changePwdPost(Model model,@Valid @ModelAttribute("PasswordModel") PasswordModel user, BindingResult result){
    Subject currentUser = SecurityUtils.getSubject();//获取当前用户
    ControllerUtils.common(model,permissionsService,"");

    if (result.hasErrors()) {
    return "change_pwd";
    }

    SysUsers sysUser = usersService.getUserByUsername(currentUser.getPrincipals().toString());
    if(sysUser!=null) {
    if(!sysUser.getPassword().equals(ParseMD5.parseStrToMd5L32(user.getOldPwd()))){
    model.addAttribute("error", "原密码错误");
    return "change_pwd";
    }
    if(!user.getNewPwd().equals(user.getRePwd())){
    model.addAttribute("error", "二次密码不一致");
    return "change_pwd";
    }

    if(ParseMD5.parseStrToMd5L32(user.getNewPwd()).equals(ParseMD5.parseStrToMd5L32(user.getOldPwd()))){
    model.addAttribute("error", "新密码和原密码一样");
    return "change_pwd";
    }

    usersService.changePassword(sysUser.getId(), ParseMD5.parseStrToMd5L32(user.getNewPwd()));
    model.addAttribute("error", "密码修改成功,请使用新密码重新登录!");
    }else{
    model.addAttribute("error", "用户不存在");
    }

    return "change_pwd";
    }

    }


    package net.lcheng.manage.controller;

    import net.lcheng.commons.utils.ParseMD5;
    import net.lcheng.manage.vo.LoginEntity;
    import net.lcheng.model.SysUsers;
    import net.lcheng.service.SysUsersService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    import javax.validation.Valid;

    /**
    * Created by qiliping on 15/12/1.
    * 登录Controller
    */
    @Controller
    public class LoginController {
    @Autowired
    private SysUsersService sysUsersService;

    /**
    * 登录GET
    */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String Index(Model model) {
    if (!model.containsAttribute("LoginEntity")) {
    model.addAttribute("LoginEntity", new LoginEntity());
    }
    return "login";
    }


    /***
    * 用户登陆
    * <p>注解配置,只允许POST提交到该方法
    *
    * @param username
    * @param password
    * @return
    */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(Model model, @Valid @ModelAttribute("LoginEntity") LoginEntity user, BindingResult result) {
    if (result.hasErrors()) {
    return "login";
    }
    SysUsers userModel = sysUsersService.getUserByUsername(user.getUsername());

    if (userModel != null) {
    String inputPwd = ParseMD5.parseStrToMd5L32(user.getPassword());
    if (!userModel.getPassword().equals(inputPwd)) {
    model.addAttribute("error", "登录密码错误");
    return "login";
    }
    if (userModel.getStatus() != 1) {
    model.addAttribute("error", "无效的用户");
    return "login";
    }
    //登录成功
    SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
    return "redirect:/main";
    } else {
    model.addAttribute("error", "用户不存在");
    return "login";
    }

    }

    /***
    * 退出
    * @param model
    * @return
    */
    @RequestMapping(value = "logout")
    public String logout(Model model) {

    SecurityUtils.getSubject().logout();

    return "redirect:/login";

    }

    /***
    * 验证参数是否为空
    *
    * @param params
    * @return
    */
    private boolean checkParams(String[] params) {
    for (String param : params) {
    if (param == "" || param == null || param.isEmpty()) {
    return false;
    }
    }
    return true;
    }
    }
  • 相关阅读:
    java7底层源码
    google的collection
    2017年八大顶尖的技术趋势
    【译】STM32L4x6系列用户手册第四章
    FRDM-KL43开发板驱动段式液晶SLCD的实现方法
    如何根据丝印查找相关的产品型号
    Arduino Tian开发板:一个功能强大的天气预报中心
    在STM32F746G-DISCO开发板上使用Nabto + FreeRTOS的演示热泵应用
    为LPC1549 LPCXpresso评估板开发基于mbed的项目
    使用LPCXpresso开发板调试外部的电路板
  • 原文地址:https://www.cnblogs.com/LvLoveYuForever/p/5623555.html
Copyright © 2011-2022 走看看