Apache Shiro

4个POJO

/**
 * @description:菜单
 */
@Entity
@Table(name = "T_MENU")
public class Menu {
    @Id
    @GeneratedValue
    @Column(name = "C_ID")
    private int id;
    @Column(name = "C_NAME")
    private String name; // 菜单名称
    @Column(name = "C_PAGE")
    private String page; // 访问路径
    @Column(name = "C_PRIORITY")
    private Integer priority; // 优先级
    @Column(name = "C_DESCRIPTION")
    private String description; // 描述

    @ManyToMany(mappedBy = "menus")
    private Set<Role> roles = new HashSet<Role>(0);

    @OneToMany(mappedBy = "parentMenu")
    private Set<Menu> childrenMenus = new HashSet<Menu>();

    @ManyToOne
    @JoinColumn(name = "C_PID")
    private Menu parentMenu;
/**
 * @description:权限名称
 */
@Entity
@Table(name = "T_PERMISSION")
public class Permission {

    @Id
    @GeneratedValue
    @Column(name = "C_ID")
    private int id;
    @Column(name = "C_NAME")
    private String name; // 权限名称
    @Column(name = "C_KEYWORD")
    private String keyword; // 权限关键字,用于权限控制
    @Column(name = "C_DESCRIPTION")
    private String description; // 描述

    @ManyToMany(mappedBy = "permissions")
    private Set<Role> roles = new HashSet<Role>(0);
/**
 * @description:角色
 */
@Entity
@Table(name = "T_ROLE")
public class Role {
    @Id
    @GeneratedValue
    @Column(name = "C_ID")
    private int id;
    @Column(name = "C_NAME")
    private String name; // 角色名称
    @Column(name = "C_KEYWORD")
    private String keyword; // 角色关键字,用于权限控制
    @Column(name = "C_DESCRIPTION")
    private String description; // 描述

    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<User>(0);

    @ManyToMany
    @JoinTable(name = "T_ROLE_PERMISSION", joinColumns = {
            @JoinColumn(name = "C_ROLE_ID", referencedColumnName = "C_ID") }, inverseJoinColumns = {
                    @JoinColumn(name = "C_PERMISSION_ID", referencedColumnName = "C_ID") })
    private Set<Permission> permissions = new HashSet<Permission>(0);

    @ManyToMany
    @JoinTable(name = "T_ROLE_MENU", joinColumns = {
            @JoinColumn(name = "C_ROLE_ID", referencedColumnName = "C_ID") }, inverseJoinColumns = {
                    @JoinColumn(name = "C_MENU_ID", referencedColumnName = "C_ID") })
    private Set<Menu> menus = new HashSet<Menu>(0);
/**
 * @description:后台用户
 */
@Entity
@Table(name = "T_USER")
public class User {

    @Id
    @GeneratedValue
    @Column(name = "C_ID")
    private int id; // 主键
    @Column(name = "C_BIRTHDAY")
    private Date birthday; // 生日
    @Column(name = "C_GENDER")
    private String gender; // 性别
    @Column(name = "C_PASSWORD")
    private String password; // 密码
    @Column(name = "C_REMARK")
    private String remark; // 备注
    @Column(name = "C_STATION")
    private String station; // 状态
    @Column(name = "C_TELEPHONE")
    private String telephone; // 联系电话
    @Column(name = "C_USERNAME", unique = true)
    private String username; // 登陆用户名
    @Column(name = "C_NICKNAME")
    private String nickname; // 真实姓名

    @ManyToMany
    @JoinTable(name = "T_USER_ROLE", joinColumns = {
            @JoinColumn(name = "C_USER_ID", referencedColumnName = "C_ID") }, inverseJoinColumns = {
                    @JoinColumn(name = "C_ROLE_ID", referencedColumnName = "C_ID") })
    private Set<Role> roles = new HashSet<Role>(0);

在web.xml中配置filter

<!-- 配置 shiro的filter-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

配置applicationContext-shiro.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: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:jpa="http://www.springframework.org/schema/data/jpa" 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
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 配置Shiro核心Filter  -->
    <bean id="shiroFilter"
        class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 安全管理器 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 未认证,跳转到哪个页面  -->
        <property name="loginUrl" value="/login.html" />
        <!-- 登录页面页面 -->
        <property name="successUrl" value="/index.html" />
        <!-- 认证后,没有权限跳转页面 -->
        <property name="unauthorizedUrl" value="/unauthorized.html" />
        <!-- shiro URL控制过滤器规则  -->
        <property name="filterChainDefinitions">
            <value>
                /login.html* = anon
                /user_login.action* = anon
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /services/** = anon
                /pages/base/courier.html* = perms[courier:list]
                /pages/base/area.html* = roles[base]
                /** = authc
            </value>
        </property>
    </bean>

    <!-- 安全管理器  -->
    <bean id="securityManager"
        class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm" />
    </bean>
    <bean id="lifecycleBeanPostProcessor"
        class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>

基于shiro登录的部分核心代码

        // 基于shiro实现登录
        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken authenticationToken = new UsernamePasswordToken(model.getUsername(), model.getPassword());

        try {
            subject.login(authenticationToken);
            return SUCCESS;
        } catch (AuthenticationException e) {
            //登录失败
            e.printStackTrace();
            return "login";
        }

realm类

@Service("bosRealm")
public class BosRealm extends AuthorizingRealm{
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //根据当前登录的用户查询对应角色和权限
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        //查询角色
        List<Role> roles = roleService.findByUser(user);
        for (Role role : roles) {
            authorizationInfo.addRole(role.getKeyword());
        }
        //查询权限
        List<Permission> permissions = permissionService.findByUser(user);
        for (Permission permission : permissions) {
            authorizationInfo.addStringPermission(permission.getKeyword());
        }
        return authorizationInfo;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //转换taken
        UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
        //根据用户名查询用户信息
        User user = userService.findByUsername(passwordToken.getUsername());
        if(user == null) {
            //用户名不存在,
            return null;
        }else {
            //用户名存在
            //当用户返回密码时,securityManager安全管理器,自动比较返回密码和用户输入密码是否一致,
            //密码一致.登录成功,密码不一致,报出异常
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }

}
时间: 2024-10-24 02:27:07

Apache Shiro的相关文章

Apache Shiro 使用手册(一)Shiro架构介绍

一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - 访问控制: 密码加密 - 保护或隐藏数据防止被偷窥: 会话管理 - 每用户相关的时间敏感的状态. 对于任何一个应用程序,Shiro都可以提供全面的安全管理服务.并且相对于其他安全框架,Shiro要简单的多. 二.Shiro的架构介绍 首先,来了解一下Shiro的三个核心组件:Subject. Security

在 Web 项目中应用 Apache Shiro

Apache Shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证.授权.加密.会话管理等功能.认证和授权为权限控制的核心,简单来说,"认证"就是证明你是谁? Web 应用程序一般做法通过表单提交用户名及密码达到认证目的."授权"即是否允许已认证用户访问受保护资源.关于 Shiro 的一系列特征及优点,很多文章已有列举,这里不再逐一赘述,本文重点介绍 Shiro 在 Web Application 中如何实现验证码认证以及如何实现单点登录. 用户权限模型

拦截404页面时tomcat抛出异常: org.apache.shiro.UnavailableSecurityManagerException

404页面中包含shiro标签,当访问404页面时,抛出异常: 原因:shiro拦截器配置缺少 标红部分,缺少红色部分导致在serverlet在拦截404页面的时候没有经过shiro  从而使shiro标签解析失败引发错误. <filter-mapping>    <filter-name>shiroFilter</filter-name>    <url-pattern>/*</url-pattern> <dispatcher>RE

Apache Shiro系列(1)

Apache Shiro是啥呢,安全框架. 360百科是这么描述的:        Apache Shiro(日语"堡垒(Castle)"的意思)是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理功能,可为任何应用提供安全保障 - 从命令行应用.移动应用到大型网络及企业应用. Shiro为解决下列问题(我喜欢称它们为应用安全的四要素)提供了保护应用的API: 认证 - 用户身份识别,常被称为用户"登录"; 授权 - 访问控制; 密码加密 - 保护或隐

Apache Shiro 使用手册(二)Shiro 认证

认证就是验证用户身份的过程.在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法.最常见的"实体/凭证"组合便是"用户名/密码"组合. 一.Shiro认证过程 1.收集实体/凭据信息 Java代码   //Example using most common scenario of username/password pair: UsernamePasswordToken token = new Userna

Apache Shiro系列四:Shiro的架构

Shiro的设计目标就是让应用程序的安全管理更简单.更直观. 软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如果用户登录了我们的系统,我就给他们显示一个按钮,点击之后可以查看他自己的账户信息.如果没有登录,我就给他显示一个注册按钮.” 上述应用程序在很大程度上是为了满足用户的需求而编写的,即便这个“用户”不是人,而是一个其他的软件系统.你仍然是按照谁当前正在与你的系统交互的逻辑来编写你的逻辑代码. Shiro的设计

Apache Shiro学习笔记(九)Spring集成

鲁春利的工作笔记,好记性不如烂笔头 Integrating Apache Shiro into Spring-based Applications Shiro 的组件都是JavaBean/POJO 式的组件,所以非常容易使用Spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web 应用的集成. Web Applications 1.web.xml <!-- The filter-name matches name of a 'shiroFil

Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor

1.错误描述 Caused by: java.lang.ClassNotFoundException: org.apache.shiro.spring.LifecycleBeanPostProcessor at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRe

Apache shiro(4)-缓存

shiro的可以权限控制内容包括:URL地址.Web页面的元素.以及方法,即shiro对用户权限的控制是细粒度的.从用户的一次访问来说,他可能需要最多经过三种.多次的验证.这里的多次怎么说呢?如果说Web页面的有10个元素加了Shiro标签,则一个页面的加载就需要10次验证.一句话:Shiro验证用户权限的频率很高,即访问数据库取得用户权限信息的频率很高.同时,用户的权限信息,是基本稳定的.很明显,这样的情景需要--缓存. shiro对缓存的支持 shiro并没有实现缓存的功能,shiro的缓存

SpringMVC+Apache Shiro+JPA(hibernate)整合配置

序: 关于标题: 说是教学,实在愧不敢当,但苦与本人文笔有限,实在找不到更合理,谦逊的词语表达,只能先这样定义了. 其实最真实的想法,只是希望这个关键词能让更多的人浏览到这篇文章,也算是对于自己写文章的一个肯定吧.^_^! 关于内容: 再写这系列文章之前,本人和许多人一样都是伸手党,并深深的了解咱伸手党且英文较差的朋友对于新知识的学习及获取中文资料少的痛苦.所以本着"取之于民,共享与民"的原则,记录下实际工作中对SpringMVC+Shiro整合应用的部分心得.本人技术水平有限,仅希望