项目目录结构
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>com.xiangshuai</groupId>
<artifactId>shiro-web2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>shiro-web Maven Webapp</name>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml") spring test
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId> <!--spring 提供在基础 IoC 功能上的扩展服务 -->
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId> <!--Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架 -->
<version>4.2.4.RELEASE</version>
</dependency>
<!-- shiro核心包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<!-- shiro 集成spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- shiro web包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<!--JdbcReals需从数据库获取数据 mysql连接驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- JdbcReals需从数据库获取数据 数据库连接池 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
<!--这个JAVA8_HOME 插件在 D:\installation\installation\maven\maven-shiro\maven_home\conf\settings.xml
中已定义好,具体定义参照 E:\学习文档子目录压缩\maven\eclipse第一次创建maven项目套路.docx
-->
<build>
<!-- 配置了很多插件 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA8_HOME}/bin/javac</executable>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:web="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd "
version="2.4">
<!--由于我用的是version="2.4"而eclipse默认的是2.5,所以需去此项目在eclipse workspace 下
D:\installation\installation\eclipse\workspace\shiro-web1\.settings\org.eclipse.wst.common.project.facet.core.xml
改成2.4如下 <installed facet="jst.web" version="2.4"/>
否则会报 maven项目eclipse提示Cannot change version of project facet Dynamic web module to 2.5
-->
<!-- 指定Spring的配置文件 -->
<!-- 否则Spring会默认从WEB-INF下寻找配置文件,contextConfigLocation属性是Spring内部固定的 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring.xml</param-value>
</context-param>
<!-- 防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 -->
<!-- <listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener> -->
<!-- 实例化Spring容器 -->
<!-- 应用启动时,该监听器被执行,它会读取Spring相关配置文件,其默认会到WEB-INF中查找applicationContext.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决乱码问题 -->
<!-- forceEncoding默认为false,此时效果可大致理解为request.setCharacterEncoding("UTF-8") -->
<!-- forceEncoding=true后,可大致理解为request.setCharacterEncoding("UTF-8")和response.setCharacterEncoding("UTF-8") -->
<filter>
<filter-name>SpringEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SpringEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->
<!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->
<!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->
<!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- SpringMVC核心分发器 -->
<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*:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring test
Demo.java
package com.xiangshuai.demo;
import java.util.Set;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xiangshuai.dao.UserDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring/spring.xml")
public class Demo {
@Resource(name="userDaoimpl")
private UserDao userDao;
@Test
public void test1(){
System.out.println(userDao);
Set<String> set = userDao.getPermissionByUsername("刘少峰");
System.out.println(set);
}
@Test
public void test2(){
System.out.println(userDao);
Set<String> set = userDao.getRolesByUsername("刘少峰");
System.out.println(set);
}
@Test
public void test3(){
System.out.println(userDao);
String password = userDao.getPasswordByUsername("刘少峰");
System.out.println(password);
}
}
配置文件
spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/shiro"></property>
<property name="username" value="root"></property>
<property name="password" value="password"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<import resource="spring-dao.xml"/>
<context:component-scan base-package="com.xiangshuai.dao"/>
<!-- 创建SecurityManger环境-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="realm"></property>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<property name="loginUrl" value="login.html"></property>
<property name="unauthorizedUrl" value="403.html"></property>
<!-- 基本系统级别权限配置-->
<property name="filterChainDefinitions" >
<value> <!-- 从上往下匹配,匹配成功及返回,不进行下面的匹配了,anon放行,auth是认证,roles角色,roleOR[]中括号数据中的任意一个都可以 -->
/login.html = anon <!-- 登录相关不拦截 -->
/subLogin = anon <!-- subLogin提交登录请求的url也不要拦截-->
/* = authc
<!--
/register/* = anon
/index.html = authc
/addItem* = authc,roles[数据管理员]
/file* = authc,roleOR[普通用户,数据管理员]
/listItems* = authc,roleOR[数据管理员,普通用户]
/showItem* = authc,roleOR[数据管理员,普通用户]
/updateItem*=authc,roles[数据管理员]
-->
<!-- /** = anon --><!-- 其他不拦截 -->
</value>
</property>
</bean>
<bean id="realm" class="com.xiangshuai.shiro.realmPasswordMatcher.Md5CustomerRealm">
<!--
//当数据库中的密码是加密数据时 -lqx
//设置Realm密码 md5将密码从数据库或MAP中解密
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//加密匹配器
matcher.setHashAlgorithmName("md5");//加密算法名为md5
matcher.setHashIterations(1);//可选择多次-,这里设置加密次数为1-因为数据库存储的密码只被MD5加密一次
md5CustomerRealm.setCredentialsMatcher(matcher);//将加密对象设置进来
Md5CustomerRealm super.setName("customRealm"); //父类 AuthorizingRealm中的 name 属性为customRealm
// 当数据库中的密码是加密数据时 -lqx
defaultSecurityManager.setRealm(md5CustomerRealm);
-->
<property name="credentialsMatcher" ref="matcher"></property>
<!-- 设置父类 AuthorizingRealm中的 name 属性为customRealm 代码SimpleAuthenticationInfo 验证时要用-->
<property name="name" value="customRealm"/>
</bean>
<bean name="matcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
<property name="hashIterations" value="1"/>
</bean>
</beans>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 配置自定扫描的包 -->
<context:component-scan base-package="com.xiangshuai.controller"/>
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 静态资源放行springmvc -->
<mvc:resources location="/" mapping="/**/*.html"/>
<mvc:resources location="/" mapping="/**/*.js"/>
<mvc:resources location="/" mapping="/**/*.css"/>
<mvc:resources location="/" mapping="/**/*.png"/>
<mvc:resources location="/" mapping="/**/*.gif"/>
</beans>
shiro.sql
/*
Navicat MySQL Data Transfer
Source Server : test
Source Server Version : 50087
Source Host : localhost:3306
Source Database : shiro
Target Server Type : MYSQL
Target Server Version : 50087
File Encoding : 65001
Date: 2019-03-11 23:22:20
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_permissions
-- ----------------------------
DROP TABLE IF EXISTS `t_permissions`;
CREATE TABLE `t_permissions` (
`permission_name` varchar(255) NOT NULL COMMENT '权限名',
KEY `permission_name` (`permission_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_permissions
-- ----------------------------
INSERT INTO `t_permissions` VALUES ('*');
INSERT INTO `t_permissions` VALUES ('user:add');
INSERT INTO `t_permissions` VALUES ('user:delete');
INSERT INTO `t_permissions` VALUES ('user:select');
INSERT INTO `t_permissions` VALUES ('user:update');
-- ----------------------------
-- Table structure for t_roles
-- ----------------------------
DROP TABLE IF EXISTS `t_roles`;
CREATE TABLE `t_roles` (
`role_name` varchar(255) NOT NULL,
KEY `role_name` (`role_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_roles
-- ----------------------------
INSERT INTO `t_roles` VALUES ('admin');
INSERT INTO `t_roles` VALUES ('sjy');
INSERT INTO `t_roles` VALUES ('superadmin');
-- ----------------------------
-- Table structure for t_roles_permissions
-- ----------------------------
DROP TABLE IF EXISTS `t_roles_permissions`;
CREATE TABLE `t_roles_permissions` (
`rolename` varchar(255) NOT NULL COMMENT '角色名-一个角色也可以对应多个用户',
`permissionname` varchar(255) NOT NULL COMMENT '一个用户又很多角色',
KEY `pk_roles_rolename` (`rolename`),
KEY `pk_permissions_permissionname` (`permissionname`),
CONSTRAINT `pk_permissions_permissionname` FOREIGN KEY (`permissionname`) REFERENCES `t_permissions` (`permission_name`),
CONSTRAINT `pk_roles_rolename` FOREIGN KEY (`rolename`) REFERENCES `t_roles` (`role_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_roles_permissions
-- ----------------------------
INSERT INTO `t_roles_permissions` VALUES ('admin', 'user:add');
INSERT INTO `t_roles_permissions` VALUES ('admin', 'user:update');
INSERT INTO `t_roles_permissions` VALUES ('admin', 'user:select');
INSERT INTO `t_roles_permissions` VALUES ('sjy', 'user:select');
INSERT INTO `t_roles_permissions` VALUES ('superadmin', 'user:add');
INSERT INTO `t_roles_permissions` VALUES ('superadmin', 'user:delete');
INSERT INTO `t_roles_permissions` VALUES ('superadmin', 'user:select');
INSERT INTO `t_roles_permissions` VALUES ('superadmin', 'user:update');
INSERT INTO `t_roles_permissions` VALUES ('superadmin', '*');
-- ----------------------------
-- Table structure for t_users
-- ----------------------------
DROP TABLE IF EXISTS `t_users`;
CREATE TABLE `t_users` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL COMMENT '王小米密码 12345加 yan MD5加密的',
`comment` varchar(500) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_users
-- ----------------------------
INSERT INTO `t_users` VALUES ('王小米', '123', null);
INSERT INTO `t_users` VALUES ('张绍峰', '123', null);
INSERT INTO `t_users` VALUES ('王凯凯', '123', null);
INSERT INTO `t_users` VALUES ('刘少峰', 'c629497ab255cb1a56e9df3f78418944', '密码是由123456 和 yan MD5加密');
-- ----------------------------
-- Table structure for t_user_roles
-- ----------------------------
DROP TABLE IF EXISTS `t_user_roles`;
CREATE TABLE `t_user_roles` (
`username` varchar(255) NOT NULL COMMENT '用户名',
`rolename` varchar(255) NOT NULL COMMENT '此用户的角色名'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_user_roles
-- ----------------------------
INSERT INTO `t_user_roles` VALUES ('王小米', 'sjy');
INSERT INTO `t_user_roles` VALUES ('张绍峰', 'sjy');
INSERT INTO `t_user_roles` VALUES ('张绍峰', 'admin');
INSERT INTO `t_user_roles` VALUES ('王凯凯', 'superadmin');
INSERT INTO `t_user_roles` VALUES ('王凯凯', 'admin');
INSERT INTO `t_user_roles` VALUES ('王凯凯', 'sjy');
INSERT INTO `t_user_roles` VALUES ('刘少峰', 'admin');
Md5CustomerRealm.java
package com.xiangshuai.shiro.realmPasswordMatcher;
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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import com.xiangshuai.dao.UserDao;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
/**
* @author lqx ,密码用MD5 存在数据库--这里存在MAP中,并加盐
* @create 2019-03-06 22:47
*/
public class Md5CustomerRealm extends AuthorizingRealm {
@Resource(name="userDaoimpl")
private UserDao userDao;
//做权限用的 -- 将用户的权限验证对象返回
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获得用户名
String userName = (String) principalCollection.getPrimaryPrincipal();
//根据用户名获得 用户角色,用户权限,从数据库中获取
Set<String> permissions = userDao.getPermissionByUsername(userName);
Set<String> roles = userDao.getRolesByUsername(userName);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;//将用户的权限验证对象返回
}
//做认证用的 -- 认证就是看用subject户名和密码在Realm是否存在 --将用户的认证对象AuthenticationInfo返回
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//从主体传过来的信息中获取用户名
String username= (String) authenticationToken.getPrincipal();
//根据用户名获得 密码,本来要从数据库中获取,这里测试直接从我们自己造的Map中获取
String password= userDao.getPasswordByUsername(username);
if(password==null){
return null;
}
//"customRealm" 是AuthorizingRealm中setName好的
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, "customRealm");
//lqx --如果数据库中的 密码 存储有加盐操作,那么 authenticationInfo这个验证对象也要设置 盐
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("yan"));//这个 "yan"是和密码做为md5 做为盐的值
//lqx
return authenticationInfo;//将用户的认证对象AuthenticationInfo返回
}
/*
* 之前 realm 是我梦自己造好放map中的
public static void main(String[] args) {
String string = new Md5CustomerRealm().upMap.get("xiaomi");
System.out.println("----"+string);
}
HashMap<String, String> upMap = new HashMap<>();
{
//构造代码块每次创建对象构造方法调用前都会被调用
//将"123456" MD5加密后放入Map中,本来应该将MD5密码放到数据库中的
Md5Hash md5password = new Md5Hash("123456","yan");//用密码 "123456"和盐 "yan" 计算出md5值存入数据库,这里存入map中
System.out.println(md5password);
upMap.put("xiaomi",md5password.toString());
super.setName("customRealm");
}
public String getPasswordByUsername(String username){
String password = upMap.get(username);
return password;
}
public Set<String> getRolesByUsername(String username){
Set<String> roles = new HashSet<String>();
roles.add("admin");
roles.add("sjy");
return roles;
}
public Set<String> getPermissionByUsername(String username){
Set<String> permissions = new HashSet<String>();
permissions.add("user:select");
permissions.add("user:update");
return permissions;
}
*
*/
}
dao层
UserDao.java
package com.xiangshuai.dao;
import java.util.Set;
public interface UserDao {
public Set<String> getPermissionByUsername(String userName);
public Set<String> getRolesByUsername(String userName);
public String getPasswordByUsername(String username);
}
UserDaoimpl.java
package com.xiangshuai.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository("userDaoimpl")
public class UserDaoimpl implements UserDao{
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public Set<String> getPermissionByUsername(String userName) {
String sql="select tp.permission_name permission_name from t_permissions tp,t_roles_permissions trp,t_user_roles tur,t_roles tr,t_users tu"
+ " where trp.rolename=tr.role_name and trp.permissionname=tp.permission_name and tur.username=tu.username "
+ "and tur.rolename=tr.role_name and tu.username="+"'"+userName+"'";
List<String> list = jdbcTemplate.query(sql, new RowMapper<String>(){
@Override
public String mapRow(ResultSet rs, int arg1) throws SQLException {
String pn = rs.getString("permission_name");
return pn;
}
});
Set<String> set = new HashSet<String>(list);
return set;
}
@Override
public Set<String> getRolesByUsername(String userName) {
String sql="select tr.role_name role_name from t_user_roles tur,t_roles tr,t_users tu"
+ " where tur.username=tu.username "
+ "and tur.rolename=tr.role_name and tu.username="+"'"+userName+"'";
List<String> list = jdbcTemplate.query(sql, new RowMapper<String>(){
@Override
public String mapRow(ResultSet rs, int arg1) throws SQLException {
//将每条记录 封装成 new RowMapper<String> 的T 返回T自动放入list中
String rn = rs.getString("role_name");
return rn;
}
});
Set<String> set=new HashSet<String>(list);
return set;
}
@Override
public String getPasswordByUsername(String userName) {
String sql="select password from t_users where username="+"'"+userName+"'";
List<String> list = jdbcTemplate.query(sql, new RowMapper<String>(){
@Override
public String mapRow(ResultSet rs, int arg1) throws SQLException {
String password = rs.getString("password");
return password;
}
});
if(list.size()>0){
return list.get(0);
}
return null;
}
}
controller 层
package com.xiangshuai.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xiangshuai.vo.User;
/**
* maven 项目
* @author lqx
* 因为IDEA操作出现错误,故再次用eclispe进行操作,
* maven 项目- 文件位置:E:\学习文档子目录压缩\框架\shiro\shiro安全框架入门\复习步骤7-获取权限数据CustomRealm提供subject桥梁,集成spring - 数据库获取用户权限角色等信息-shiro加密密码和盐存入数据库或map\
* 我的网盘/我的笔记/学习文档子目录压缩\框架\shiro\shiro安全框架入门\复习步骤7-获取权限数据CustomRealm提供subject桥梁,集成spring - 数据库获取用户权限角色等信息-shiro加密密码和盐存入数据库或map\
* @create 2019-03-08 21:20
*/
@Controller
public class UserController {
//produces = "application/json; charset=utf-8" 解决@ResponseBody 返回中文乱码
@RequestMapping(value = "/subLogin",method = RequestMethod.POST
,produces = "application/json; charset=utf-8")
@ResponseBody
public String subLogin(User user){
Subject subject =SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
try {
subject.login(token);
System.out.println(subject.isAuthenticated());
System.out.println(subject.hasRole("admin"));
}catch (Exception e){
return e.getMessage();//将错误信息JSON响应到页面
}
return "登录成功";
}
}
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="subLogin" method="post">
用户名: <input name="username" type="text"/>
密码:<input name="password" type="password"/>
<input value="提交" type="submit"/>
</form>
</body>
</html>
页面效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="subLogin" method="post">
用户名: <input name="username" type="text"/>
密码:<input name="password" type="password"/>
<input value="提交" type="submit"/>
</form>
</body>
</html>
刘少峰 123456 登录