我们知道在SSM整合shiro时,需要在web.xml中配置
<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置true由servlet容器控制filter的生命周期 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiro</param-value>
</init-param>
</filter>
还有在xml中配置基本的
<!-- 注册自定义Realm -->
<bean class="com.hrm.realm.MyRealm" id="myRealm">
<!-- 配置凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher" />
</bean>
<!-- 注册SecurityManager -->
<bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager">
<!-- 配置自定义Realm -->
<property name="realm" ref="myRealm"/>
</bean>
<!-- 注册ShiroFilterFactoryBean 注意id必须和web.xml中注册的targetBeanName的值一致 -->
<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"
id="shiro">
<!-- 注册SecurityManager -->
<property name="securityManager" ref="securityManager" />
<!-- 登录地址 如果用户请求的的地址是 login.do 那么会对该地址认证 -->
<property name="loginUrl" value="/login.do" />
<!-- 登录成功的跳转地址 -->
<property name="successUrl" value="jsp/success.jsp" />
<!-- 访问未授权的页面跳转的地址 -->
<property name="unauthorizedUrl" value="jsp/refuse.jsp" />
<!-- 设置 过滤器链 -->
<property name="filterChainDefinitions">
<value>
<!--加载顺序从上往下。
authc需要认证
anon可以匿名访问的资源
-->
/login.do=authc
/**=anon
</value>
</property>
</bean>
总结一下,在SSM中整合Shiro需要在web.xml中配置代理,需要在xml配置文件中注册自定义的realm、SecurityManager、ShiroFilterFactoryBean
那么在SpringBoot也同样是要基本配置这些东西,只不过不是用xml配置文件里进行配置的,而是使用配置类来进行配置。
第一种方式:
依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
这里使用的Shiro依赖是shiro-web和shiro-spring,而不是shiro-spring-boot-web-starter
。
ShiroConfig
相当于在SSM整合Shiro中的配置文件中一些配置,这里主要是注册了上面所讲的三个bean。这里使用的是ShiroFilterFactoryBean
,而不是ShiroFilterChainDefinition
。
/**
* @author ZSL
* @ClassName ShiroConfig
* @description
* @date 2019/8/13
*/
@Configuration
public class ShiroConfig{
@Bean
MyRealm myRealm(){
return new MyRealm();
}
@Bean
SecurityManager securityManager(){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean(){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
bean.setLoginUrl("/login");
bean.setSuccessUrl("/index");
bean.setUnauthorizedUrl("/unindex");
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("/login","anon");
map.put("/**","authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
自定义realm
/**
* @author ZSL
* @ClassName MyRealm
* @description
* @date 2019/8/13
*/
public class MyRealm extends AuthorizingRealm {
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String) authenticationToken.getPrincipal();
if (!"zsl".equals(username)){
return null;
}
return new SimpleAuthenticationInfo(username,"zsl",null,getName());
}
}
controller
/**
* @author ZSL
* @ClassName LoginController
* @description
* @date 2019/8/13
*/
@RestController
public class LoginController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
@PostMapping("/login")
public void login(String username,String password) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
System.out.println("---------success----------");
} catch (AuthenticationException e) {
e.printStackTrace();
}
}
}
第二种方式:
依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
这里使用的是shiro-spring-boot-web-starter
,是围绕Springboot而打造的一系列依赖之一,所以这里有很多配置和原先的不太一样,但是整体还是配置那些。
在application.properties中配置一些Shiro的配置
#是否允许将sessionId 放到 cookie 中
shiro.sessionManager.sessionIdCookieEnabled=true
#是否允许将 sessionId 放到 Url 地址拦中
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
#访问未获授权的页面时,默认的跳转路径
shiro.unauthorizedUrl=/unauthorizedurl
#开启 shiro
shiro.web.enabled=true
#登录成功的跳转页面
shiro.successUrl=/index
#登录页面
shiro.loginUrl=/login
自定义realm
这里的realm和第一种方式的一样,没什么特别需要去更改的。
/**
* @author ZSL
* @ClassName MyRealm
* @description
* @date 2019/8/13
*/
public class MyRealm extends AuthorizingRealm {
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String) authenticationToken.getPrincipal();
if (!"zsl".equals(username)){
return null;
}
return new SimpleAuthenticationInfo(username,"zsl",null,getName());
}
}
ShiroConfig
/**
* @author ZSL
* @ClassName ShiroConfig
* @description
* @date 2019/8/13
*/
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm(){
return new MyRealm();
}
@Bean
DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterChainDefinition shiroFilterChainDefinition (){
DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition = new DefaultShiroFilterChainDefinition();
defaultShiroFilterChainDefinition.addPathDefinition("/login","anon");
defaultShiroFilterChainDefinition.addPathDefinition("/**","authc");
return defaultShiroFilterChainDefinition;
}
}
这里的ShiroConfig相当于shiro在SSM的xml配置,也是注册三个bean,而和在SSM整合Shiro的xml所不同的是,
这里使用的是DefaultWebSecurityManager
而不是SecurityManager
。
其实吧,看源码,你会发现DefaultWebSecurityManager
是SecurityManager
的实现类。
这里注册的bean不是ShiroFilterFactoryBean
而是ShiroFilterChainDefinition
,
Controller
/**
* @author ZSL
* @ClassName LoginController
* @description
* @date 2019/8/13
*/
@RestController
public class LoginController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
@PostMapping("/login")
public void login(String username,String password) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
System.out.println("---------success----------");
} catch (AuthenticationException e) {
e.printStackTrace();
}
}
}
总结
方式一使用的是在SSM中整合Shiro的方法,将 SSM 整合 Shiro 的配置用 Java 重写一遍。
方式二使用的是使用 Shiro 官方提供的一个 Starter 来配置。