【springboot shiro】(4)Spring Boot与Shiro整合实现用户认证

1.1. 分析Shiro的核心API Subject: 用户主体(把操作交给SecurityManager)

SecurityManager:安全管理器(关联Realm)

Realm:Shiro连接数据的桥梁

1.2. Spring Boot整合Shiro 1.2.1. 导入shiro与spring整合依赖 修改pom.xml

org.apache.shiro

shiro-spring

1.4.0

1.2.2. 自定义Realm类 package com.itheima.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;

/**

  • 自定义Realm

  • @author lenovo

*/

public class UserRealm extends AuthorizingRealm{

/**

  • 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

/**

  • 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

return null;

}

}

1.2.3. 编写Shiro配置类(*) package com.itheima.shiro;

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;

/**

  • Shiro的配置类

  • @author lenovo

*/

@Configuration

public class ShiroConfig {

/**

  • 创建ShiroFilterFactoryBean

*/

@Bean

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

shiroFilterFactoryBean.setSecurityManager(securityManager);

return shiroFilterFactoryBean;

}

/**

  • 创建DefaultWebSecurityManager

*/

@Bean(name="securityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

//关联realm

securityManager.setRealm(userRealm);

return securityManager;

}

/**

  • 创建Realm

*/

@Bean(name="userRealm")

public UserRealm getRealm(){

return new UserRealm();

}

}

1.3. 使用Shiro内置过滤器实现页面拦截 package com.itheima.shiro;

import java.util.LinkedHashMap;

import java.util.Map;

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;

/**

  • Shiro的配置类

  • @author lenovo

*/

@Configuration

public class ShiroConfig {

/**

  • 创建ShiroFilterFactoryBean

*/

@Bean

public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//设置安全管理器

shiroFilterFactoryBean.setSecurityManager(securityManager);

//添加Shiro内置过滤器

/**

  • Shiro内置过滤器,可以实现权限相关的拦截器

  • 常用的过滤器:

  •   anon: 无需认证(登录)可以访问
    
  •   authc: 必须认证才可以访问
    
  •   user: 如果使用rememberMe的功能可以直接访问
    
  •   perms: 该资源必须得到资源权限才可以访问
    
  •   role: 该资源必须得到角色权限才可以访问
    

*/

Map<String,String> filterMap = new LinkedHashMap<String,String>();

/*filterMap.put("/add", "authc");

filterMap.put("/update", "authc");*/

filterMap.put("/testThymeleaf", "anon");

filterMap.put("/*", "authc");

//修改调整的登录页面

shiroFilterFactoryBean.setLoginUrl("/toLogin");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

return shiroFilterFactoryBean;

}

/**

  • 创建DefaultWebSecurityManager

*/

@Bean(name="securityManager")

public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

//关联realm

securityManager.setRealm(userRealm);

return securityManager;

}

/**

  • 创建Realm

*/

@Bean(name="userRealm")

public UserRealm getRealm(){

return new UserRealm();

}

}

1.4. 实现用户认证(登录)操作 1.4.1. 设计登录页面

登录页面

登录

用户名:

密码:

1.4.2. 编写Controller的登录逻辑

/**

  • 登录逻辑处理

*/

@RequestMapping("/login")

public String login(String name,String password,Model model){

/**

  • 使用Shiro编写认证操作

*/

//1.获取Subject

Subject subject = SecurityUtils.getSubject();

//2.封装用户数据

UsernamePasswordToken token = new UsernamePasswordToken(name,password);

//3.执行登录方法

try {

subject.login(token);

//登录成功

//跳转到test.html

return "redirect:/testThymeleaf";

} catch (UnknownAccountException e) {

//e.printStackTrace();

//登录失败:用户名不存在

model.addAttribute("msg", "用户名不存在");

return "login";

}catch (IncorrectCredentialsException e) {

//e.printStackTrace();

//登录失败:密码错误

model.addAttribute("msg", "密码错误");

return "login";

}

}

1.4.3. 编写Realm的判断逻辑 package com.itheima.shiro;

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.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

/**

  • 自定义Realm

  • @author lenovo

*/

public class UserRealm extends AuthorizingRealm{

/**

  • 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

/**

  • 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

//假设数据库的用户名和密码

String name = "eric";

String password = "123456";

//编写shiro判断逻辑,判断用户名和密码

//1.判断用户名

UsernamePasswordToken token = (UsernamePasswordToken)arg0;

if(!token.getUsername().equals(name)){

//用户名不存在

return null;//shiro底层会抛出UnKnowAccountException

}

//2.判断密码

return new SimpleAuthenticationInfo("",password,"");

}

}

1.5. 整合MyBatis实现登录 1.5.1. 导入mybatis相关的依赖

com.alibaba

druid

1.0.9

mysql

mysql-connector-java

org.mybatis.spring.boot

mybatis-spring-boot-starter

1.1.1

1.5.2. 配置application.properties 位置:src/main/resources目录下

spring.datasource.driverClassName=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/test

spring.datasource.username=root

spring.datasource.password=root

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

mybatis.type-aliases-package=com.itheima.domain

1.5.3. 编写User实体 package com.itheima.domain;

public class User {

private Integer id;

private String name;

private String password;

public Integer getId() {

return id;

}

public void setId(Integer 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;

}

}

1.5.4. 编写UserMapper接口 package com.itheima.mapper;

import com.itheima.domain.User;

public interface UserMapper {

public User findByName(String name);

}

1.5.5. 编写UserMapper.xml映射文件

1.5.6. 编写业务接口和实现 接口:

package com.itheima.service;

import com.itheima.domain.User;

public interface UserService {

public User findByName(String name);

}

实现;

package com.itheima.service.impl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.itheima.domain.User;

import com.itheima.mapper.UserMapper;

import com.itheima.service.UserService;

@Service

public class UserServiceImpl implements UserService{

//注入Mapper接口

@Autowired

private UserMapper userMapper;

@Override

public User findByName(String name) {

return userMapper.findByName(name);

}

}

1.5.7. 添加@MapperScan注解 package com.itheima;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

  • SpringBoot启动类

  • @author lenovo

*/

@SpringBootApplication

@MapperScan("com.itheima.mapper")

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

1.5.8. 修改UserRealm package com.itheima.shiro;

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.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

import org.springframework.beans.factory.annotation.Autowired;

import com.itheima.domain.User;

import com.itheima.service.UserService;

/**

  • 自定义Realm

  • @author lenovo

*/

public class UserRealm extends AuthorizingRealm{

/**

  • 执行授权逻辑

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {

System.out.println("执行授权逻辑");

return null;

}

@Autowired

private UserService userSerivce;

/**

  • 执行认证逻辑

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {

System.out.println("执行认证逻辑");

//编写shiro判断逻辑,判断用户名和密码

//1.判断用户名

UsernamePasswordToken token = (UsernamePasswordToken)arg0;

User user = userSerivce.findByName(token.getUsername());

if(user==null){

//用户名不存在

return null;//shiro底层会抛出UnKnowAccountException

}

//2.判断密码

return new SimpleAuthenticationInfo("",user.getPassword(),"");

}

}


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!