springboot+shiro简单登录认证

springboot+shiro简单登录认证

模拟从数据库取信息

1、实体类
注:@Data节省了set、get方法。@AllArgsConstructor在@Data基础上有参构造。
@Data
@AllArgsConstructor
public class User {
    private String id;
    private String userName;
    private String password;
    /**
     * 用户对应的角色集合
     */
    private Set<Role> roles;
}
@Data
@AllArgsConstructor
public class Role {

    private String id;
    private String roleName;
    //角色对应权限集合
     
    private Set<Permissions> permissions;

}
@Data
@AllArgsConstructor
public class Permissions {
    private String id;
    private String permissionsName;
}
2、编写service层实现类模拟数据
/**
 * 模拟数据库查询
 *
 * @param userName 用户名
 * @return User
 */
private User getMapByName(String userName) {
    Permissions permissions1 = new Permissions("1", "query");
    Permissions permissions2 = new Permissions("2", "add");
    Set<Permissions> permissionsSet = new HashSet<>();
    permissionsSet.add(permissions1);
    permissionsSet.add(permissions2);
    Role role = new Role("1", "admin", permissionsSet);
    Set<Role> roleSet = new HashSet<>();
    roleSet.add(role);
    User user = new User("1", "wsl", "123456", roleSet);
    Map<String, User> map = new HashMap<>();
    map.put(user.getUserName(), user);

    Set<Permissions> permissionsSet1 = new HashSet<>();
    permissionsSet1.add(permissions1);
    Role role1 = new Role("2", "user", permissionsSet1);
    Set<Role> roleSet1 = new HashSet<>();
    roleSet1.add(role1);
    User user1 = new User("2", "zhangsan", "123456", roleSet1);
    map.put(user1.getUserName(), user1);
    return map.get(userName);
}
3、Realm代码

注:在获取账号操作,principals.getPrimaryPrincipal();这一步强转的对象是与下一个方法体中,new SimpleAuthenticationInfo(username,user.getPassword(),getName());第一个参数所对应。

public class UserRealm  extends AuthorizingRealm {

    @Autowired
    private LoginService loginService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取登录账号
        String username = (String) principals.getPrimaryPrincipal();
        //获取登录账号的信息
        User user = loginService.getUserByName(username);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for(Role role:user.getRoles()){
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            for (Permissions permissions : role.getPermissions()){
                simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
            }
        }
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
      if (StringUtils.isEmpty(token.getPrincipal())){
        return null;
      }
      //获取用户信息
        String username  = token.getPrincipal().toString();
      User user = loginService.getUserByName(username);
      if (user == null){
        return null;
      }else {
        SimpleAuthenticationInfo simpleAuthorizationInfo =new SimpleAuthenticationInfo(
                username,user.getPassword(),getName()
        );
        return simpleAuthorizationInfo;
      }
    }
}
4、配置shiro拦截器
@Configuration
public class ShiroConfig {

    //@conditionalOnMissingBean,唯一bean,如果有相同的则该注解不生成。(个人理解)
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

	//前面写的Realm(自己写的话换成自己的Realm)
    @Bean
    public UserRealm realm(){
        return new UserRealm();
    }

    //权限管理
    @Bean
    public SecurityManager securityManager (){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(realm());
        return defaultWebSecurityManager;
    }

    //Filer工厂,设置过滤
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean  = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map =new HashMap<>();
        map.put("/","anon");
        map.put("/loginOut","anon");
        map.put("/**","authc");
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //成功
        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //注入权限管理
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
5、Controller层
@Controller
public class LoginContorller {

    @Autowired
    private LoginService service;
    
    @RequestMapping("/login")
    public String login(HttpServletRequest request){
        String username = request.getParameter("account");
        String password = request.getParameter("password");
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(
            username,password
        );
        try {
            //进行验证,这里可以捕获异常,然后返回对应信息
            subject.login(token);
        } catch (UnknownAccountException e) {
            return "用户名不存在!";
        } catch (AuthenticationException e) {
            return "账号或密码错误!";
        } catch (AuthorizationException e) {
            return "没有权限";
        }
        return "hello";
    }

    //Model是前端界面结合了点thymeleaf运用,可以不用考虑
    @RequestMapping("/hello")
    public String hello(Model model){
        //存入数据
        model.addAttribute("msg","<h1 style='color:red'>Hello</h1>");
        model.addAttribute("users", Arrays.asList("小红", "小米","小白"));
        return "hello";
    }
}
6、前端界面
登录
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 4.0 Strict//EN" "TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<div><h1 id="say"></h1></div>
<div align="center">
    <form action="/login" method="get">
    <table>
        <thead>
            <th colspan="3" align="center">SpringBoot 登录</th>
        </thead>
        <tbody>
        <tr >
            <td >
               <label for="account">账号:</label>
            </td>
            <td>
                <input name="account" id="account" />
            </td>
        </tr>
        <tr >
            <td >
               <label for="password">密码</label>
            </td>
            <td>
                <input name="password" id="password" />
            </td>
        </tr>

        <tr >
            <td >
                <input name="submit" type="submit" value="登录" />
            </td>
            <td>
                <input name="reset" type="reset" value="重置" />
            </td>
        </tr>
        </tbody>
    </table>
    </form>
</div>

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

</body>
</html>
主界面
<!DOCTYPE html>
<html lang="en"
      xmlns:shiro="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      >
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>success</h1>

<!--Thymeleaf语法:th:text就是将div中的内容设置为它指定的值-->

<div th:text="${msg}">你好</div>
<!--utext:会解析html,显示相应的效果-->
<div th:utext="${msg}">你好</div>
<!--each:遍历-->
<h3 th:each="user:${users}" th:text="${user}"></h3>

    <h1>测试:<shiro:principal/></h1>

    <shiro:hasPermission name="query">
        用户[<shiro:principal/>]拥有权限
        <br/>
    </shiro:hasPermission>

    <shiro:hasRole name="admin">
        用户[<shiro:principal/>]拥有角色admin<br/>
    </shiro:hasRole>
</body>
</html>

附上架包

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

记了又忘只能记笔记呜呜

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值