Once you choose at least one user store to connect to for Shiro’s needs, we’ll need to configure a Realm that represents that data store and then tell the ShiroSecurityManager about it.
If you’ve checked out the step2 branch, you’ll notice the src/main/webapp/WEB-INF/shiro.ini file’s [main] section now has the following additions:
中文翻译:一旦您为Shiro的需要选择了至少一个要连接到的用户商店,我们将需要配置一个Realm,它表示数据存储,然后告诉ShiroSecurityManager关于这件事。
如果您已经检查了step2布兰奇,你会注意到src/main/webapp/WEB-INF/shiro.ini档案[main]一节现在增加了以下内容
# Configure a Realm to connect to a user datastore. In this simple tutorial,
# we'll just point to Stormpath since it
# takes 5 minutes to set up:
stormpathClient = com.stormpath.shiro.client.ClientFactory
stormpathClient.cacheManager = $cacheManager
# (Optional) If you put your apiKey.properties in the non-default location, you set the location here
#stormpathClient.apiKeyFileLocation = $HOME/.stormpath/apiKey.properties
stormpathRealm = com.stormpath.shiro.realm.ApplicationRealm
stormpathRealm.client = $stormpathClient
# Find this URL in your Stormpath console for an application you create:
# Applications -> (choose application name) --> Details --> REST URL
# (Optional) If you only have one Application
# stormpathRealm.applicationRestUrl = https://api.stormpath.com/v1/applications/$STORMPATH_APPLICATION_ID
stormpathRealm.groupRoleResolver.modeNames = name
securityManager.realm = $stormpathRealm
这个
这个
这个
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListenerlistener-class>
listener>
<filter>
<filter-name>ShiroFilterfilter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilterfilter-class>
filter>
<filter-mapping>
<filter-name>ShiroFilterfilter-name>
<url-pattern>/*url-pattern>
<dispatcher>REQUESTdispatcher>
<dispatcher>FORWARDdispatcher>
<dispatcher>INCLUDEdispatcher>
<dispatcher>ERRORdispatcher>
filter-mapping>
<filter>
<filter-name>shiroFilterfilter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
<init-param>
<param-name>targetFilterLifecycleparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>shiroFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.jsp"/>
<property name="successUrl" value="/home.jsp"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/> -->
<property name="filterChainDefinitions">
<value>
# some example chain definitions:
/admin/** = authc, roles[admin]
/docs/** = authc, perms[document:read]
/** = authc
# more URL-to-FilterChain definitions here
value>
property>
bean>
<bean id="someFilter" class="..."/>
<bean id="anotherFilter" class="..."> ... bean>
...
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean id="myRealm" class="...">
...
bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
bean>
在spring整合shiro过程中,不需要添加EnvironmentLoaderListener这个监听器,是因为spring的ContentLoadListener 已经代替EnvironmentLoaderListener初始化容器并加载配置shiro的配置文件,所以spring整合shiro以后不需要配置EnvironmentLoaderListener。
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.3.2version>
dependency>
<filter>
<filter-name>shiroFilterfilter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
<init-param>
<param-name>targetFilterLifecycleparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>shiroFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
package com.zhijin.web.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* 自定义reamlm
*/
public class AuthRealm extends AuthorizingRealm {
//登陆认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//强转为用户名密码token
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
//得页面传的登录名
String email = upToken.getUsername();
//从数据库中查询登录名
User user = userService.findUserByEmail(email);
if (user != null){
//封装到认证对象中
//第一个参数:安全数据(user对象)
//第二个参数:密码(数据库密码)
//第三个参数:当前调用realm域的名称(类名即可)
return new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
}
return null;
}
// 授权访问校验
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User) principals.getPrimaryPrincipal();
if (user !=null) {
//根据用户的ID从数据库中查询出权限模块
List<Module> moduleList = moduleService.findModuleByUserId(user.getId());
Set<String> permissions = new HashSet<>();
for (Module module : moduleList) {
//将查询出的模块名称添加到set集合中
permissions.add(module.getName());
}
SimpleAuthorizationInfo sia = new SimpleAuthorizationInfo();
//将带有模块名称的set结合添加到SimpleAuthorizationInfo(封装授权对象)
sia.addStringPermissions(permissions);
return sia;
}
return null;
}
}
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 1. 配置shiro过滤器工厂 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--配置引用安全管理器-->
<property name="securityManager" ref="securityManager"/>
<!--登录页面-->
<property name="loginUrl" value="/login.jsp"/>
<!--没有权限默认跳转的页面,登录的用户访问了没有被授权的资源自动跳转到的页面-->
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<!--配置过滤规则-->
<property name="filterChainDefinitions">
<value>
<!--
anno:任何人可以访问
authc:必须登录后才能访问,不包括remember me
user:登录用户才可以访问,包含remember me
perms:指定过滤规则,这个一般是扩展使用,不会使用原生的
-->
/index.jsp* = anon
/login.jsp* = anon
/login* = anon
/logout* = anon
/css/** = anon
/img/** = anon
/plugins/** = anon
/make/** = anon
/** = authc
package com.zhijin.web.shiro;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
public class CustomCredentialsMatcher extends HashedCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
//获取用户输入的登录名
String username = (String) token.getPrincipal();
//获取用户输入的登录密码
String password = new String((char[])token.getCredentials());
//获取数据库查出来的密码
String md5Password = new Md5Hash(password,username).toString();
String dbPassword = (String) info.getCredentials();
return md5Password.equals(dbPassword);
}
}
//1.获取subject
Subject subject = SecurityUtils.getSubject();
//2.构造用户名和密码
UsernamePasswordToken upToken = new UsernamePasswordToken(email, password);
//3.借助subject完成用户登录
subject.login(upToken);