记录一次基于springboot2.0.4整合shiro框架,平时没有写博客的习惯,正所谓好记性不如烂笔头。

                                    Springboot2.0.4整合shiro笔记

 

 

pom.xml



    4.0.0

    com.soneer
    fp
    0.0.1-SNAPSHOT
    jar

    fp
    Demo project for Spring Boot

    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.4.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
    

    

                  
        
            org.springframework.boot
            spring-boot-starter-validation
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            1.3.2
        

        
        
            org.springframework.boot
            spring-boot-starter-aop
            2.0.4.RELEASE
        

        
            org.springframework.boot
            spring-boot-starter-thymeleaf
            2.0.4.RELEASE
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        


        
        
            org.mybatis.generator
            mybatis-generator-core
            1.3.5
        
        
        
        
            com.alibaba
            druid-spring-boot-starter
            1.1.10
        

        
        
            com.github.pagehelper
            pagehelper-spring-boot-starter
            1.2.5
        

        
        
            org.apache.shiro
            shiro-spring
            1.4.0
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    com.soneer.fp.FpApplication
                
            
             
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.5
                
                    true
                    true
                
                
                    
                        mysql
                        mysql-connector-java
                        5.1.46
                    
                
            
        


    



 

application.properties

server.port=8888

# Generator逆向工程
#generator.targetProject=src/main/java
#generator.javaModel-targetPackage=com.soneer.fp.pojo
#generator.sqlMap-targetPackage=com.soneer.fp.mapper
#generator.javaClient-targetPackage=com.soneer.fp.mapper

#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false//开发环境设为false,生产环节根据需要去设置
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

mybatis.mapper-locations=classpath:mapper/*.xml

#durid连接池
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.druid.url = jdbc:mysql://localhost:3306/sone
spring.datasource.druid.username=root
spring.datasource.druid.password=sone920801

#初始化时建立物理连接的个数,初始化发生在显示调用init方法,或者第一次getConnection时
spring.datasource.druid.initial-size=5
#最大连接池数量
spring.datasource.druid.max-active=100
#最小连接池数量
spring.datasource.druid.min-idle=5
#获取连接时最大等待时间,单位毫秒
spring.datasource.druid.max-wait=60000
#是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大
spring.datasource.druid.pool-prepared-statements=true

spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#用来检测连接是否有效的sql,要求是一个查询语句
spring.datasource.druid.validation-query=SELECT * FROM user

spring.datasource.druid.validation-query-timeout=60000
#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
spring.datasource.druid.test-on-borrow=false
#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
spring.datasource.druid.test-on-return=false
#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
spring.datasource.druid.test-while-idle=true
#	有两个含义:
#1) Destroy线程会检测连接的间隔时间
# 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=100000

# WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*


# StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
spring.datasource.druid.stat-view-servlet.enabled= true
spring.datasource.druid.stat-view-servlet.url-pattern= /druid/*
spring.datasource.druid.stat-view-servlet.reset-enable= false
spring.datasource.druid.stat-view-servlet.login-username= admin
spring.datasource.druid.stat-view-servlet.login-password= admin
spring.datasource.druid.stat-view-servlet.allow= 127.0.0.1
#spring.datasource.druid.stat-view-servlet.deny= 192.168.32.139 #访问黑名单

# 配置StatFilter
spring.datasource.druid.filter.stat.db-type=mysql
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=5000

# 配置WallFilter
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=mysql
spring.datasource.druid.filter.wall.config.delete-allow=false
spring.datasource.druid.filter.wall.config.drop-table-allow=false

#pagehelper分页
logging.level.com.soneer.fp.service=DEBUG
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
pagehelper.page-size-zero=true


目录结构

记录一次基于springboot2.0.4整合shiro框架,平时没有写博客的习惯,正所谓好记性不如烂笔头。_第1张图片

这里圈出来的不用管它,pom和application文件都已经去除配置了。

cosrConfig里面是用于跨域配置的。

annotation里面是我自定义的注解。

author里面是通过aop来做api调用身份认证的(相关的依赖和配置均已去除,且不管它)。

下面进入正题!

DruidConfig类
package com.soneer.fp.datasource;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import javax.sql.DataSource;

@Configuration
@ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.alibaba.druid.pool.DruidDataSource", matchIfMissing = true)
public class DruidConfig {

    /**
     * @see

     * @return DruidDataSource
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid")
    public DataSource dataSourceOne(){
        return DruidDataSourceBuilder.create().build();
    }

}


DruidStatFilter类
package com.soneer.fp.datasource;

import com.alibaba.druid.support.http.WebStatFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

/**
 * Servlet Filter implementation class DruidFilter
 */
@WebFilter(
        filterName="druidWebStatFilter",
        urlPatterns= {"/*"},
        initParams= {
                @WebInitParam(name="exclusions",value="*.js,*.jpg,*.png,*.gif,*.ico,*.css,/druid/*")//配置本过滤器放行的请求后缀
        }
)
public class DruidStatFilter extends WebStatFilter {
}

DruidStatViewServlet 类

package com.soneer.fp.datasource;

import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.Servlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

/**
 * Servlet implementation class DruidStateViewServlet
 */
@WebServlet(
        urlPatterns= {"/druid/*"},
        initParams= {
                @WebInitParam(name="allow",value="127.0.0.1"),
                @WebInitParam(name="loginUsername",value="root"),
                @WebInitParam(name="loginPassword",value="123"),
                @WebInitParam(name="resetEnable",value="true")// 允许HTML页面上的“Reset All”功能

        }
)
public class DruidStatViewServlet extends StatViewServlet implements Servlet {
    private static final long serialVersionUID = 1L;


}


 

LoginUser类

package com.soneer.fp.pojo;

import java.io.Serializable;

public class LoginUser implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private int userId;
	private String userName;
	private String trueName;
	private String userType;
	private String password;
	private String duty;
	private String unit;
	private String phone;
	private int rolesId;
	private Integer bfId;
	private Integer approles;
	
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getTrueName() {
		return trueName;
	}
	public void setTrueName(String trueName) {
		this.trueName = trueName;
	}
	public String getUserType() {
		return userType;
	}
	public void setUserType(String userType) {
		this.userType = userType;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getDuty() {
		return duty;
	}
	public void setDuty(String duty) {
		this.duty = duty;
	}
	public String getUnit() {
		return unit;
	}
	public void setUnit(String unit) {
		this.unit = unit;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public int getRolesId() {
		return rolesId;
	}
	public void setRolesId(int rolesId) {
		this.rolesId = rolesId;
	}
	public Integer getBfId() {
		return bfId;
	}
	public void setBfId(Integer bfId) {
		this.bfId = bfId;
	}
	public Integer getApproles() {
		return approles;
	}
	public void setApproles(Integer approles) {
		this.approles = approles;
	}
	
	@Override
	public String toString() {
		return "LoginUser [userId=" + userId + ", userName=" + userName + ", trueName=" + trueName + ", userType="
				+ userType + ", password=" + password + ", duty=" + duty + ", unit=" + unit + ", phone=" + phone
				+ ", rolesId=" + rolesId + ", bfId=" + bfId + ", approles=" + approles + "]";
	}
	
}

 

ShiroConfig类

package com.soneer.fp.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * Shiro配置类
 * 1.配置ShiroFilterFactory 2.配置SecurityManager
 * @author zhengkai
 *
 */
@Configuration
public class ShiroConfig {
    @Resource
    private UserRealm userRealm;
    /**
     * 配置shiro过滤器
     * @author zhengkai
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager")SecurityManager securityManager) {
        //1.定义shiroFactoryBean
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //2.设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //3.LinkedHashMap是有序的,进行顺序拦截器配置
        Map filterChainMap = new LinkedHashMap();
        //4.配置logout过滤器
        filterChainMap.put("/logout", "logout");
        //登陆和主页不需要认证
        filterChainMap.put("/login","anon");
        filterChainMap.put("/","anon");
        filterChainMap.put("/checkLogin","anon");
        filterChainMap.put("/css/**", "anon"); //匿名访问静态资源
        filterChainMap.put("/js/**", "anon"); //匿名访问静态资源
        filterChainMap.put("/fonts/**", "anon"); //匿名访问静态资源
        filterChainMap.put("/images/**", "anon"); //匿名访问静态资源
        filterChainMap.put("/lib/**", "anon"); //匿名访问静态资源


        //5.所有url必须通过认证才可以访问
        filterChainMap.put("/**","authc");

        //6.设置默认登录的url
        shiroFilterFactoryBean.setLoginUrl("/login");
        //7.设置成功之后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //8.设置未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        //9.设置shiroFilterFactoryBean的FilterChainDefinitionMap
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }
    /**
     * 配置安全管理器
     * @author zhengkai
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm.
        securityManager.setRealm(userRealm);//将自定义的realm注入到securityManager中
        return securityManager;
    }

}

自定义UserRealm类

package com.soneer.fp.shiro;


import javax.annotation.Resource;

import com.soneer.fp.pojo.LoginUser;
import com.soneer.fp.service.impl.LoginUserBizImpl;
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.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import org.jboss.logging.Logger;
import org.springframework.stereotype.Component;

@Component
public class UserRealm extends AuthorizingRealm {
	
	private Logger logger=Logger.getLogger(getClass());

	@Resource
	private LoginUserBizImpl userBiz;
	
	 //用户角色和权限授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection Principal){
		String userName=(String)Principal.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
		try {
			authorizationInfo.setRoles(userBiz.chkRoleName(userName));
			authorizationInfo.setStringPermissions(userBiz.chkPermissions(userName));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println(authorizationInfo);
		return authorizationInfo;
	}
   
	//用户身份登陆认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String userName = token.getUsername();
		logger.info("doGetAuthenticationInfo username--------->:"+userName);
		
		
		String username=(String)token.getPrincipal();
		//String username=userName;
		try {
			LoginUser user=userBiz.chkByUserName(username);
			if(user!=null){
				//System.out.println(user.getUserName()+"===="+user.getPassword());
				AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"userRealm");
				return authcInfo;
			}else {
				return null;
			}
			
		} catch (Exception e) {
			System.out.println("身份认证失败");
		}
		return null;
	}

}

可能有的人注意到了上面注解@Component  这里是要将UserRealm这个类注入到securityManager中才能起到作用,这里我一开始在上面的ShiroCongfig类中没有将自定义UserRealm这个类注入进去,导致报错No realms have been configured! One or more realms must be 。。。。

 

LoginUserMapper


import com.soneer.fp.pojo.LoginUser;
import org.apache.ibatis.annotations.Param;


public interface LoginUserMapper {
	/**
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	LoginUser loginByuser(@Param("username") String username, @Param("password") String password);
   /**
    * 
    * @param username
    * @return
    */
	LoginUser chkByUserName(@Param("username") String username);
   /**
    * 
    * @return
    * @param username
    */
   Set chkRoleName(@Param("username") String username);
   /**
    * 
    * @param username
    * @return
    * @throws Exception
    */
   Set chkPermissions(String username);

}

LoginUserMapper.xml





	
        
                    

你可能感兴趣的:(随笔,springboot,shiro)