• springboot集成shiro


    一、概念

      Shiro是一个Java安全框架,可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。

    Subject:即当前用户,在权限管理的应用程序里往往需要知道谁能够操作什么,谁拥有操作该程序的权利,shiro中则需要通过Subject来提供基础的当前用户信息,Subject 不仅仅代表某个用户,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。

    SecurityManager:管理所有Subject,这是Shiro框架的核心组件,可以把他看做是一个Shiro框架的全局管理组件,用于调度各种Shiro框架的服务。

    Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),可以看成数据库。

    认证流程:

    使用流程:

     1. 自定义realm

     2.构建SecurityManager环境

     3.提交认证,将携带的信息储存在 UsernamePasswordToken中

    UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);

     4.获取subject

    Subject subject = SecurityUtils.getSubject();

    5.登录

    subject.login(usernamePasswordToken);

    二、代码

    代码层级

    1.pom文件

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId>springboot-shiro-10095</artifactId>
    	
    	<parent>
    	  	<groupId>org.springframework.boot</groupId>
    	  	<artifactId>spring-boot-starter-parent</artifactId>
    	  	<version>2.0.2.RELEASE</version>
    	  	<relativePath/>
      	</parent>
    	<dependencies>
    		<dependency>
            	<groupId>org.springframework.boot</groupId>
            	<artifactId>spring-boot-devtools</artifactId>
            </dependency>
    		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<version>5.1.44</version>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.4</version>
            </dependency>
            <!-- shiro -->
            <dependency>
    		    <groupId>org.apache.shiro</groupId>
    		    <artifactId>shiro-spring</artifactId>
    		    <version>1.3.2</version>
    		</dependency>
    	</dependencies>
    	
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<configuration>
    					<source>1.8</source>
    					<target>1.8</target>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
     
    </project>
    

      

    2.application.yml

    server:
      port: 10095
    spring:
      application:
        name: shiro
    #  zipkin:
    #    base-url: http://127.0.0.1:10092
    #eureka
    #eureka: 
    #  client:
    #    service-url:
    #      defaultZone: http://localhost:10090/eureka/
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: update
      http:
        encoding:
          charset: utf-8
          enabled: true
    

    3.关于shiro的表5张,利用JPA自动生成

    (1)User 用户表

    /**  
     * All rights Reserved
     * @Title:  User.java   
     * @Package com.yanwu.www.entity   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:05:58   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.entity;
    
    import java.util.List;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**   
     * @ClassName:  User   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:05:58   
     *     
     * @Copyright: 2018 
     */
    @Entity(name="user")
    public class User {
    	@Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        
        private String name;
        private String password;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
        
    }
    

      

    (2)Role 角色表

    /**  
     * All rights Reserved
     * @Title:  Role.java   
     * @Package com.yanwu.www.entity   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:07:43   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**   
     * @ClassName:  Role   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:07:43   
     *     
     * @Copyright: 2018 
     */
    @Entity
    public class Role {
    	@Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String roleName;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getRoleName() {
            return roleName;
        }
    
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
    }

     

    (3)Permission 权限表

    /**  
     * All rights Reserved
     * @Title:  Permission.java   
     * @Package com.yanwu.www.entity   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:12:42   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**   
     * @ClassName:  Permission   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:12:42   
     *     
     * @Copyright: 2018 
     */
    @Entity
    public class Permission {
    	
    	@Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    	
        private String permission;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getPermission() {
            return permission;
        }
    
        public void setPermission(String permission) {
            this.permission = permission;
        }
    }
    

    (4)UserRole 用户和角色关联

    /**  
     * All rights Reserved
     * @Title:  UserRole.java   
     * @Package com.yanwu.www.entity   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:15:24   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**   
     * @ClassName:  UserRole   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:15:24   
     *     
     * @Copyright: 2018 
     */
    @Entity
    public class UserRole {
    	@Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    	
    	private String userId;
    	
    	private String roleId;
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getUserId() {
    		return userId;
    	}
    
    	public void setUserId(String userId) {
    		this.userId = userId;
    	}
    
    	public String getRoleId() {
    		return roleId;
    	}
    
    	public void setRoleId(String roleId) {
    		this.roleId = roleId;
    	}
    }
    

      

    (5)RolePermission 角色和权限关联

    /**  
     * All rights Reserved
     * @Title:  RolePermission.java   
     * @Package com.yanwu.www.entity   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:17:02   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**   
     * @ClassName:  RolePermission   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:17:02   
     *     
     * @Copyright: 2018 
     */
    @Entity
    public class RolePermission {
    	
    	@Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    	
    	private String roleId;
    	
    	private String permissionId;
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getRoleId() {
    		return roleId;
    	}
    
    	public void setRoleId(String roleId) {
    		this.roleId = roleId;
    	}
    
    	public String getPermissionId() {
    		return permissionId;
    	}
    
    	public void setPermissionId(String permissionId) {
    		this.permissionId = permissionId;
    	}
    	
    }	
    

    4.自定义realm(需要继承AuthorizingRealm)

    /**  
     * All rights Reserved
     * @Title:  UserRealm.java   
     * @Package com.yanwu.www.config   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:48:54   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.config;
    
    import java.util.List;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import com.yanwu.www.entity.Permission;
    import com.yanwu.www.entity.Role;
    import com.yanwu.www.entity.User;
    import com.yanwu.www.repository.PermissionRipository;
    import com.yanwu.www.repository.RoleRipository;
    import com.yanwu.www.repository.UserRipository;
    
    /**   
     * @ClassName:  UserRealm   
     * @Description: 自定义realm   
     * @author: harvey
     * @date:   2018年8月30日 下午2:48:54   
     *     
     * @Copyright: 2018 
     */
    @Component
    public class MyShiroRealm extends AuthorizingRealm{
    
    	@Autowired
    	private UserRipository userRipository;
    	
    	@Autowired
    	private RoleRipository roleRipository;
    	
    	@Autowired
    	private PermissionRipository permissionRipository;
    	
    	/**   
    	 * <p>Title: doGetAuthorizationInfo</p>   
    	 * <p>Description: </p>   
    	 * @param arg0
    	 * @return   
    	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)   
    	 */
    	@Override
    	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    		
    		//获取登录用户名
            String username= (String) principalCollection.getPrimaryPrincipal();
            //查询用户名称
            User user = userRipository.findByName(username);
            
            //添加角色和权限
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            List<Role> roles = roleRipository.findRolesByUserId(user.getId().toString());
            for(Role role : roles){
            	// 添加角色
            	simpleAuthorizationInfo.addRole(role.getRoleName());
            	for(Permission permission : permissionRipository.findPermissionsByRoleId(role.getId().toString())){
            		// 添加权限
            		simpleAuthorizationInfo.addStringPermission(permission.getPermission());
            	}
            }
            
            return simpleAuthorizationInfo;
    		
    	}
    
    	/**   
    	 * <p>Title: doGetAuthenticationInfo</p>   
    	 * <p>Description: </p>   
    	 * @param arg0
    	 * @return
    	 * @throws AuthenticationException   
    	 * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)   
    	 */
    	@Override
    	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    		
    		// 1.把AuthenticationToken转为UsernamePasswordToken对象
    		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    
    		// 2.从UsernamePasswordToken获取username
    		String userName = upToken.getUsername();
    
    		// 3.调用数据库方法,从数据库中查询username对应的用户记录
    		System.out.println("从数据库中获取信息userName:" + userName + "所对应信息");
    		User user = userRipository.findByName(userName);
    		
    		// 4.若用户不存在,则可以抛出异常
    		if (null == user) {
    			throw new UnknownAccountException("用户不存在");
    		}
    		
    		// 5.根据用户情况,来构建AuthenticationInfo对象并返回,通常使用的实现类是SimpleAuthenticationInfo
    		
    		// 1)principal,用户名,认证实体,可以是实体,也可以是数据表对应的实体类对象
    		Object principal = userName;
    		
    		// 2)credential,密码,明文密码,即构建UsernamePasswordToken对象时的密码
    		Object credentials = user.getPassword().toString();
    		
    		// 3)realmName:当前realm对象的name,调用父类的getName即可
    		String realmName = getName();
    		
    		// 4.盐值(避免同一密码加密时产生相同的字符串,一般是用用户名做盐值)
    		ByteSource credentialsSalt = ByteSource.Util.bytes(userName);
    
    		// 不加密
    		//SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);
    		
    		// 加密
    		SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials, credentialsSalt, realmName);
    
    		return info;
    	}
    	
    	
    	// 增加用户时可以使用SimpleHash产生加密后的密码字符串存入数据库,避免数据库的用户密码明文显示
    	public static void main(String[] args) {
    		String algorithmName="MD5";
    		Object source="1234";
    		Object salt=ByteSource.Util.bytes("user2");
    		int hashIterations=1024;
    		Object result=new SimpleHash(algorithmName, source, salt, hashIterations);
    		System.out.println(result);
    	}
    
    }
    

    5.shiro配置类

    /**  
     * All rights Reserved
     * @Title:  ShiroConfig.java   
     * @Package com.yanwu.www.config   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:47:16   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.config;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**   
     * @ClassName:  ShiroConfig   
     * @Description:shiro配置类   
     * @author: harvey
     * @date:   2018年8月30日 下午2:47:16   
     *     
     * @Copyright: 2018 
     */
    @Configuration
    public class ShiroConfig {
    	
    	
    	/**
         * 密码校验规则HashedCredentialsMatcher
         * 这个类是为了对密码进行编码的 ,
         * 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,
         * 这个类也负责对form里输入的密码进行编码
         * 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher
         */
        @Bean
        public HashedCredentialsMatcher hashedCredentialsMatcher() {
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            //指定加密方式为MD5
            credentialsMatcher.setHashAlgorithmName("MD5");
            //加密次数
            credentialsMatcher.setHashIterations(1024);
            credentialsMatcher.setStoredCredentialsHexEncoded(true);
            return credentialsMatcher;
        }
    	
    	//将自己的验证方式加入容器
        @Bean
        public MyShiroRealm myShiroRealm() {
            MyShiroRealm myShiroRealm = new MyShiroRealm();
            
            // 设置加密方式
            myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
            
            return myShiroRealm;
        }
    
        //权限管理,配置主要是Realm的管理认证
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(myShiroRealm());
            
            return securityManager;
        }
    
        //Filter工厂,设置对应的过滤条件和跳转条件
        @Bean
        public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            Map<String,String> map = new HashMap<String, String>();
            
            //anon表示可以匿名访问,authc表示需要认证
            //登出
            map.put("/logout","anon");
            //对所有用户认证 
            map.put("/**","authc");
            //登录
            shiroFilterFactoryBean.setLoginUrl("/login");
            
            //首页
            shiroFilterFactoryBean.setSuccessUrl("/index");
            
            //错误页面,认证不通过跳转
            shiroFilterFactoryBean.setUnauthorizedUrl("/error");
            
            shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
            return shiroFilterFactoryBean;
        }
    
        //加入注解的使用,不加入这个注解不生效
        @Bean
        public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
            AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
            authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
            return authorizationAttributeSourceAdvisor;
        }
        
    }

     

    6.Repositoty

    (1)BaseRepository

    package com.yanwu.www.repository;
    
    import java.io.Serializable;
    
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.data.repository.NoRepositoryBean;
    import org.springframework.data.repository.PagingAndSortingRepository;
    /**
     * 
     * @ClassName:  BaseRepository   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:21:18   
     *   
     * @param <T>
     * @param <I>  
     * @Copyright: 2018
     */
    @NoRepositoryBean
    public interface BaseRepository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>,JpaSpecificationExecutor<T>{
    
    }
    

    (2)UserRipository

    /**  
     * All rights Reserved
     * @Title:  UserRipository.java   
     * @Package com.yanwu.www.repository   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:20:19   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.repository;
    
    import org.springframework.stereotype.Repository;
    
    import com.yanwu.www.entity.User;
    
    /**   
     * @ClassName:  UserRipository   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:20:19   
     *     
     * @Copyright: 2018 
     */
    @Repository
    public interface UserRipository extends BaseRepository<User, Long>{
    	
    	User findByName(String username);
    }
    

      

    (3)RoleRipository

    /**  
     * All rights Reserved
     * @Title:  UserRipository.java   
     * @Package com.yanwu.www.repository   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:20:19   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.repository;
    
    import java.util.List;
    
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.stereotype.Repository;
    
    import com.yanwu.www.entity.Role;
    
    /**   
     * @ClassName:  UserRipository   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:20:19   
     *     
     * @Copyright: 2018 
     */
    @Repository
    public interface RoleRipository extends BaseRepository<Role, Long>{
    	
    	@Query(value = "select distinct r.* from role r inner join role_permission rp on rp.role_id = r.id inner join user_role ur on ur.role_id = r.id where ur.user_id =?1" ,nativeQuery=true)
    	List<Role> findRolesByUserId(String userId);
    }

      

    (4)PermissionRipository

    /**  
     * All rights Reserved
     * @Title:  UserRipository.java   
     * @Package com.yanwu.www.repository   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:20:19   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.repository;
    
    import java.util.List;
    
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.stereotype.Repository;
    
    import com.yanwu.www.entity.Permission;
    
    /**   
     * @ClassName:  UserRipository   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:20:19   
     *     
     * @Copyright: 2018 
     */
    @Repository
    public interface PermissionRipository extends BaseRepository<Permission, Long>{
    	
    	@Query(value = "select distinct p.*  from permission p  inner join role_permission rp on rp.permission_id = p.id inner join role r on r.id = rp.role_id  where r.id =?1" ,nativeQuery=true)
    	List<Permission> findPermissionsByRoleId(String roleId);
    }

     

    7.service

    (1)UserService

    /**  
     * All rights Reserved
     * @Title:  UserService.java   
     * @Package com.yanwu.www.service   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:25:11   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.service;
    
    /**   
     * @ClassName:  UserService   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:25:11   
     *     
     * @Copyright: 2018 
     */
    public interface UserService {
    	/**
    	 * 
    	 * @Title: login   
    	 * @Description: 用户登录   
    	 * @param username
    	 * @param password
    	 * @return
    	 * @return: String
    	 */
    	String login(String username,String password);
    	
    	/**
    	 * 
    	 * @Title: logout   
    	 * @Description: 用户登出   
    	 * @return
    	 * @return: String
    	 */
    	String logout();
    }

    (2)UserServiceImpl

    /**  
     * All rights Reserved
     * @Title:  UserServiceImpl.java   
     * @Package com.yanwu.www.service   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午2:27:15   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.service;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    /**   
     * @ClassName:  UserServiceImpl   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午2:27:15   
     *     
     * @Copyright: 2018 
     */
    @Component
    public class UserServiceImpl implements UserService {
    
    	/**   
    	 * <p>Title: login</p>   
    	 * <p>Description: </p>   
    	 * @param username
    	 * @param password   
    	 * @see com.yanwu.www.service.UserService#login(java.lang.String, java.lang.String)   
    	 */
    	@Override
    	public String login(String username, String password) {
    		
    		if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
    			throw new UnknownAccountException("账号或者密码为空");
    		}
    		
    		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
    		
    		Subject subject = SecurityUtils.getSubject();
    		
    		try{
    			subject.login(usernamePasswordToken);
    			
    			// 设置闲置session时间
    			subject.getSession().setTimeout(5*1000);
    			return "login ok";
    		}catch( AuthenticationException e){
    			System.out.println("==========");
    			System.out.println(e.getMessage());
    		}
    		
    		return "login failure";
    
    	}
    
    	/**   
    	 * <p>Title: logout</p>   
    	 * <p>Description: </p>   
    	 * @return   
    	 * @see com.yanwu.www.service.UserService#logout()   
    	 */
    	@Override
    	public String logout() {
    		
    		Subject subject = SecurityUtils.getSubject();
    		
    		subject.logout();
    		
    		return "logout ok";
    	}
    }
    

      

    8.controller

    /**  
     * All rights Reserved
     * @Title:  UserController.java   
     * @Package com.yanwu.www.controller   
     * @Description: TODO(用一句话描述该文件做什么)   
     * @author: harvey 
     * @date:   2018年8月30日 下午3:31:43   
     * @version V1.0 
     * @Copyright: 2018
     */
    package com.yanwu.www.controller;
    
    import org.apache.shiro.authz.annotation.RequiresRoles;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.yanwu.www.service.UserService;
    
    /**   
     * @ClassName:  UserController   
     * @Description:TODO(这里用一句话描述这个类的作用)   
     * @author: harvey
     * @date:   2018年8月30日 下午3:31:43   
     *     
     * @Copyright: 2018 
     */
    @RestController
    public class UserController {
    	
    	@Autowired
    	private UserService userService;
    	
    	//登录
        @RequestMapping(value = "/login")
        public String login(String username,String password){
        	
        	String status = userService.login(username, password);
        	
            return status;
        }
        
        //首页
        @RequestMapping(value = "/index")
        public String index(){
        
            return "index";
        }
    	
    	//登出
        @RequestMapping(value = "/logout")
        public String logout(){
        	
        	userService.logout();
        	
            return "logout";
        }
    
        //错误页面展示
        @RequestMapping(value = "/error",method = RequestMethod.POST)
        public String error(){
            return "error ok!";
        }
        
        // 测试shiro注解
        @RequestMapping(value = "/test",method = RequestMethod.GET)
        @RequiresRoles(value={"admin"})
        public String test(){
            return "test ok!";
        }
        
        
    }
    

      

    三、注意点

    加密

    本博客已经配置,需要在自定义realm,securityManager进行修改,如下配置如何获得加密后的字符串

    // 增加用户时可以使用SimpleHash产生加密后的密码字符串存入数据库,避免数据库的用户密码明文显示
    public static void main(String[] args) {
      String algorithmName="MD5";
      Object source="1234";
      // 加盐
      Object salt=ByteSource.Util.bytes("user2");
      int hashIterations=1024;
      Object result=new SimpleHash(algorithmName, source, salt, hashIterations);
      System.out.println(result);
    }
    

      

  • 相关阅读:
    linux中read用法
    apt-get 使用指南
    linux文件系统
    KMP
    在C#中的各种应用
    A*算法,遗传算法
    Dijkstra算法,Floyd算法
    AE开发tips
    TOC 右键菜单
    ubuntu下的一些意外
  • 原文地址:https://www.cnblogs.com/harvey2017/p/9565288.html
Copyright © 2020-2023  润新知