使用shiro实现用户登录认证和简单权限的实现(法院项目)

onlineSchool 项目课 七:实现用户的登录功能 一,Java代码实现用户的登录注册功能。 前台: 1,点击一个a标签,请求到countroller,返回一个页面,实现返回的页面结构。 2, form表单输入用户登录或注册的用户名密码。展示验证码,点击验证码变换的效果。 3,对密码进行64位的哈希编码,并设置到输入框。 (注册还需要比对密码一致,不一致数据回滚。) 4,ajaxSubmit提交form表单,校验成功,页面跳转,校验失败,返回Java中定义的失败提示,重置输入框。 //提交登录的form表单 function doLogin() { 阅读详情
实现登录认证

步骤一:导入依赖包

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.csource</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.27-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
    </dependencies>

步骤二:构建配置文件类ShiroConfig

package com.qf.fayuan.config;

import com.qf.fayuan.bean.MyShiroFactoryBean;
import com.qf.fayuan.mapper.PermissonMapper;
import com.qf.fayuan.mapper.UserMapper;
import com.qf.fayuan.shiro.realm.MyRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;


@Configuration
public class ShiroConfig {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissonMapper permissonMapper;
    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }
    @Bean
    public MyRealm myRealm(CredentialsMatcher credentialsMatcher, UserMapper userMapper,PermissonMapper permissonMapper){
    //需要另外编写MyRealm类
        MyRealm myRealm = new MyRealm();
        myRealm.setUserMapper(userMapper);
        myRealm.setCredentialsMatcher(credentialsMatcher);
        myRealm.setPermissonMapper(permissonMapper);
        return myRealm;
    }
    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashIterations(1024);
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        return hashedCredentialsMatcher;
    }
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public FilterRegistrationBean delegatingFilterProxy() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy("shiroFilter");
        filterRegistrationBean.setFilter(delegatingFilterProxy);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setEnabled(true);
        filterRegistrationBean.addInitParameter("targetFilterLifecycle", "true");
        return filterRegistrationBean;
    }

    @Bean
    public MyShiroFactoryBean shiroFilter(SecurityManager securityManager, PermissonMapper permissonMapper) {
    //这个类也要另建
        MyShiroFactoryBean myShiroFactoryBean = new MyShiroFactoryBean();
        myShiroFactoryBean.setPermissonMapper(permissonMapper);
        myShiroFactoryBean.setSecurityManager(securityManager);
        return myShiroFactoryBean;
    }

}

第三步:创建MyRealm类

package com.qf.fayuan.shiro.realm;

import com.qf.fayuan.mapper.PermissonMapper;
import com.qf.fayuan.mapper.UserMapper;
import com.qf.fayuan.shiro.pojo.CourtAdmin;
import com.qf.fayuan.shiro.usernamepasswordtoken.UserNamePassWordToken;
import com.qf.fayuan.user.pojo.User;
import com.qf.fayuan.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;

public class MyRealm extends AuthorizingRealm {

    private UserMapper userMapper;

    private PermissonMapper permissonMapper;

    public void setPermissonMapper(PermissonMapper permissonMapper) {
        this.permissonMapper = permissonMapper;
    }

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
			return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //获取用户的用户名
        String username = ((UserNamePassWordToken) authenticationToken).getUsername();
        //获取用户的角色
        int role = ((UserNamePassWordToken) authenticationToken).getUser_role();
        //根据用户名和用户角色,从数据库中查询该用户的信息
        CourtAdmin courtAdmin = userMapper.getCourtAdmin(username,role);
        //将用户存在数据库中的盐取出并且变成字节类型
        ByteSource bytes = ByteSource.Util.bytes(courtAdmin.getSalt());
        //传入用户名,用户在数据库中真实的的密码,盐,getName();
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,courtAdmin.getPassword(),bytes,getName());
        //返回带有用户信息的对象
        return simpleAuthenticationInfo;

    }
}

步骤四:编写contorller层,实现用户的登录验证

//    @LogAnno(operationtype = "/login",operationname = "用户登陆,服务器返回用户的部分信息")
    @RequestMapping("/login")// @RequestParam(value = "user_role",required = false,defaultValue = "1")
    public ResultBean login(String userinfo, Integer user_role, String password){
    //获取当前登录用户的链接
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isAuthenticated()){
        //将用户的用户名和密码存入到UserNamePassWordToken中
            UserNamePassWordToken usernamePasswordToken = new UserNamePassWordToken(userinfo,password,user_role);
            try{
            //验证登录用户的信息是否正确,如果失败的话就会报错处理,所以需要捕获异常
                subject.login(usernamePasswordToken);
            }catch (Exception e){
                e.printStackTrace();
                return ResultBean.setError(ErrorCodeInterface.MIMACUOWU,"信息错误",null);
            }
        }
        UserVo userVo =  userService.login(userinfo,user_role);
        SecurityUtils.getSubject().getSession().setAttribute("user",userVo);
        return ResultBean.setOk(userVo);

    }

在上面中发现使用到了UserNamePassWordToken 这个对象,这个对象中可以携带几个字段,如username和password等,这个时候我想让这个对象也要携带我自定义的一个字段role,那么需要自定义一个类,让这个类去继承UserNamePassWordToken,然后添加一个新的字段role

类的内容如下:

package com.qf.fayuan.shiro.usernamepasswordtoken;

import org.apache.shiro.authc.UsernamePasswordToken;

public class UserNamePassWordToken extends UsernamePasswordToken {

    private int user_role;

    public UserNamePassWordToken(String username,String password,int user_role){
        super(username,password);
        this.user_role = user_role;
    }

    public int getUser_role() {
        return user_role;
    }

    public void setUser_role(int user_role) {
        this.user_role = user_role;
    }
}

根据上面的内容就可以使用shiro实现简单的登录认证功能了。

实现权限部分

步骤一:首先定义一个自定义注解,注解中包含,访问需要的权限(设置该路径名就是需要访问的权限) 、权限表述的相关信息

package com.qf.fayuan.anno;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissonAnno {

    String value();//权限的值,将方法或者类的路径设置为所要权限的值
    String comment();//权限的描述 ,该权限的描述不应为空或者重复
    boolean isMenu() default false;//判断是否是一个表单
    String parent();  //其父类的权限描述

}

步骤二:将注解添加到类和方法的上面

    @PermissonAnno(value = "/getnoticeinfo",comment="查询公告",isMenu = false,parent = "公告列表")

步骤三:遍历每一个类和类中的每一个方法,将权限添加到表中
首先定义一个工具类来封装注解中的信息

package com.qf.fayuan.shiro.pojo;

public class PermissonBean {

    private int id;
    private String value;
    private String comment;
    private boolean isMenu;
    private String parent;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public boolean isMenu() {
        return isMenu;
    }

    public void setMenu(boolean menu) {
        isMenu = menu;
    }

    public String getParent() {
        return parent;
    }

    public void setParent(String parent) {
        this.parent = parent;
    }

    @Override
    public String toString() {
        return "PermissonBean{" +
                "id=" + id +
                ", value='" + value + '\'' +
                ", comment='" + comment + '\'' +
                ", isMenu=" + isMenu +
                ", parent='" + parent + '\'' +
                '}';
    }
}

然后通过给定一个项目的路径,就可以扫描这个项目中的所以类和方法

package com.qf.fayuan.utils;

import com.qf.fayuan.anno.PermissonAnno;
import com.qf.fayuan.shiro.pojo.PermissonBean;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class PermissonAnnoUtils {
//  定义一个set集合用来存储判断是含有该注解的类
    private static Set<Class> classSet = new HashSet<>();
    //将直接定义在类上面的注解的信息封装到对象,然后存入到该集合中
    private static  Set<PermissonBean> classBean = new LinkedHashSet<>();
    //将定义在方法上的注解的信息封装到对象中然后存入到该集合中
    private static  Set<PermissonBean> methodBean = new LinkedHashSet<>();

    public static void getClassSet(String packagename) throws Exception {
        /**
         *  xxx.class.getResource()用来从当前类(xxx)所在的目录下(也就是以当前类所在路径为根路径)获得资源;
         * xxx.class.getClassLoader().getResource()用来从classpath路径下(也就是以classpath所在路径为根路径)获得资源。
         */

        //根据项目中一段路径(com.qf.fayuan),获得  file:/D:/idea/idea-workspace/fayuanxiangmu/target/classes/com/qf/fayuan  其中file为协议
        URL resource = PermissonAnnoUtils.class.getClassLoader().getResource(packagename.replace(".", "/"));
        if(resource!=null||"file".equalsIgnoreCase(resource.getProtocol())){
            //getProtocol获取协议:也就是   file:   部分
            String packagepath = URLDecoder.decode(resource.getFile(),"utf-8");
            ///D:/idea/idea-workspace/fayuanxiangmu/target/classes/com/qf/fayuan
            addClass(packagename,packagepath);
        }
    }

    private static void addClass(String packagename, String packagepath) throws Exception {

        //获得该路径下的所有文件,并且添加一个过滤器,设置条件
        File[] files = new File(packagepath).listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //如果是一个文件或者是一个类,或者是一个目录,就遍历进入数组中
                return (pathname.isFile() || pathname.getName().endsWith(".class") || pathname.isDirectory());
            }
        });
        for (File file : files) {
            //file的格式为:  D:\idea\idea-workspace\fayuanxiangmu\target\classes\com\qf\fayuan\anno
            //获得文件的名字
            String name = file.getName();
            //name  的值是  anno
            if(file.isFile()){
                if(!name.contains("Controller")){
                    continue;
                }
                String classname = name.substring(0,name.lastIndexOf("."));
                classname = packagename + "." +classname;
                doAddClass(classname);
            }else {
                String subpackagepath = name;
                if(!StringUtils.EmptyString(packagepath)){
                    subpackagepath = packagepath+"/"+name;
                }
                String subpackagename = name;
                if(!StringUtils.EmptyString(packagename)){
                    subpackagename = packagename+"."+name;
                }
                addClass(subpackagename,subpackagepath);
            }
        }
    }
    private static void doAddClass(String classname) throws ClassNotFoundException {
        Class<?> aClass = Class.forName(classname);
        classSet.add(aClass);
    }

    public static void inject(String packagename) throws Exception {

        classSet.clear();
        classBean.clear();
        methodBean.clear();
        getClassSet(packagename);

        for (Class clazz : classSet) {
            //扫描类上的注解
            PermissonAnno annotation = (PermissonAnno) clazz.getAnnotation(PermissonAnno.class);
            String value = null;
            String comment = null;
            boolean isMenu = false;
            String parent = null;
            String parentValue = null;
            if(annotation!=null){
                comment = annotation.comment();
                parentValue = annotation.value();
                isMenu = annotation.isMenu();
                parent = annotation.parent();
                PermissonBean permissonBean = new PermissonBean();
                permissonBean.setComment(comment);
                permissonBean.setValue(parentValue);
                permissonBean.setMenu(isMenu);
                permissonBean.setParent(parent);
                classBean.add(permissonBean);
            }
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                //扫描方法上的注解
                PermissonAnno annotation1 = method.getAnnotation(PermissonAnno.class);
                if(annotation1!=null){
                    value = annotation1.value();
                    comment = annotation1.comment();
                    isMenu = annotation1.isMenu();
                    parent = annotation1.parent();
                    value = parentValue+value;
                    PermissonBean permissonBean = new PermissonBean();
                    permissonBean.setValue(value);
                    permissonBean.setComment(comment);
                    permissonBean.setMenu(isMenu);
                    permissonBean.setParent(parent);
                    methodBean.add(permissonBean);
                }
            }
        }

    }

    public static Set<Class> getClassSet() {
        return classSet;
    }

    public static Set<PermissonBean> getClassBean() {
        return classBean;
    }

    public static Set<PermissonBean> getMethodBean() {
        return methodBean;
    }

    public static void main(String[] args) {
        File[] files = new File("D:/idea/idea-workspace/fayuanxiangmu/target/classes/com/qf/fayuan").listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                System.out.println(pathname);//D:\idea\idea-workspace\fayuanxiangmu\target\classes\com\qf\fayuan\anno
                System.out.println(pathname.getName());//anno
                return (pathname.isFile() || pathname.getName().endsWith(".class") || pathname.isDirectory());
            }
        });
        for (File file : files) {
            System.out.println(file.getName());
        }
//
//        URL resource = PermissonAnnoUtils.class.getClassLoader().getResource("com.qf.fayuan".replace(".", "/"));
//        System.out.println(resource);//file:/D:/idea/idea-workspace/fayuanxiangmu/target/classes/com/qf/fayuan
//
//        URL resource1 = PermissonAnnoUtils.class.getResource("com.qf.fayuan");
//        System.out.println(resource1);//null
//
//        String file = PermissonAnnoUtils.class.getClassLoader().getResource("com.qf.fayuan".replace(".", "/")).getFile();
//        System.out.println(file);///D:/idea/idea-workspace/fayuanxiangmu/target/classes/com/qf/fayuan

    }

}

别写controller层,访问该层,将所有的注解中的信息存入到数据库中

package com.qf.fayuan.shiro.controller;

import com.qf.fayuan.anno.PermissonAnno;
import com.qf.fayuan.bean.ResultBean;
import com.qf.fayuan.mapper.PermissonMapper;
import com.qf.fayuan.shiro.pojo.PermissonBean;
import com.qf.fayuan.utils.ErrorCodeInterface;
import com.qf.fayuan.utils.PermissonAnnoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Set;

@RequestMapping("/permisson")
@RestController()
public class PermissonController {
    @Autowired
    private PermissonMapper permissonMapper;

    @RequestMapping("/addallpermisson")
    public ResultBean addAllPermisson(){

        try {
            PermissonAnnoUtils.inject("com.qf.fayuan");
            Set<PermissonBean> classBean = PermissonAnnoUtils.getClassBean();
            permissonMapper.addAllPermisson(classBean);

            Set<PermissonBean> methodBean = PermissonAnnoUtils.getMethodBean();
            permissonMapper.addAllPermisson(methodBean);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBean.setError(ErrorCodeInterface.XIUGAIMIMASHIBAI,"失败了",null);
        }


        return ResultBean.setOk(null);
    }


}

步骤四:上面将所有的权限添加到了数据库中,下面就是将访问各个类或者方法的权限添加到shiro中

在MyShiroFactoryBean中添加代码即可

package com.qf.fayuan.bean;

import com.qf.fayuan.mapper.PermissonMapper;
import com.qf.fayuan.shiro.pojo.PermissonValue;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.List;

public class MyShiroFactoryBean extends ShiroFilterFactoryBean {
    //这里不应该使用自动注入的方式
    private PermissonMapper permissonMapper;

    public void setPermissonMapper(PermissonMapper permissonMapper) {
        this.permissonMapper = permissonMapper;
    }
//添加这个注解以为着
    @PostConstruct
    public void init(){
        //设置登录的界面的位置
        setLoginUrl("/login.html");
        //创建一个map集合,将要访问的路径和所需要的权限添加进去
        LinkedHashMap<String, String> perms = new LinkedHashMap<>();
        //访问首页,需要的权限是任何权限都可以访问
        perms.put("/index.html","anon");
        perms.put("/login.html","anon");
        //如果想访问success.html页面,必须进行登录认证,而且会自动跳转到登录界面
        perms.put("/success.html","authc");


        //将本项目的所有权限添加到添加到shiro中
       List<PermissonValue> list  = permissonMapper.getAllPermisson();
       if(list!=null){
           for (PermissonValue value : list) {
               //注意添加权限的时候,权限的书写格式
               perms.put(value.getValue(),"perms["+value.getValue()+"]");
           }
       }
        setFilterChainDefinitionMap(perms);
    }

}

这样,就设置好了访问每个页面时所需要的权限,但是只有这些还不够,因为,只是知道了访问这些界面所需要的权限,但是没有给相应用户添加权限,否则,这些界面用户是无法访问的

步骤五:将用户的所有权限遍历出来放到shiro中,让shiro自行比对
在doGetAuthorizationInfo方法中

package com.qf.fayuan.shiro.realm;

import com.qf.fayuan.mapper.PermissonMapper;
import com.qf.fayuan.mapper.UserMapper;
import com.qf.fayuan.shiro.pojo.CourtAdmin;
import com.qf.fayuan.shiro.usernamepasswordtoken.UserNamePassWordToken;
import com.qf.fayuan.user.pojo.User;
import com.qf.fayuan.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;

public class MyRealm extends AuthorizingRealm {

    private UserMapper userMapper;

    private PermissonMapper permissonMapper;

    public void setPermissonMapper(PermissonMapper permissonMapper) {
        this.permissonMapper = permissonMapper;
    }

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        UserVo user = (UserVo) SecurityUtils.getSubject().getSession().getAttribute("user");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //获取用户的所有权限
        List<String> list = userMapper.getSelfPermisson(user.getUser_id());
        if(list!=null){
            for (String s : list) {
            //将所有的权限添加到shiro中
                simpleAuthorizationInfo.addStringPermission(s);
            }
        }
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = ((UserNamePassWordToken) authenticationToken).getUsername();
        int role = ((UserNamePassWordToken) authenticationToken).getUser_role();
        CourtAdmin courtAdmin = userMapper.getCourtAdmin(username,role);
        ByteSource bytes = ByteSource.Util.bytes(courtAdmin.getSalt());
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,courtAdmin.getPassword(),bytes,getName());
        return simpleAuthenticationInfo;

    }
}

至此权限部分完成

手把手教你Shiro整合JWT实现登录认证 Component/*** 限定这个realm只能处理JwtToken*/@Override}/*** 授权(授权部分这里就省略了)*/@Override// 获取到用户名,查询用户权限}/*** 认证*/@Override// 获取token信息// 校验token:未校验通过或者已过期if (!throw new AuthenticationException("token已失效,请重新登录");}//用户信息。 阅读详情

相关推荐

基于shiro实现的用户登录系统

基于shiro实现的用户登录系统,运行sql文件更改数据库连接可直接运行,项目集成了mybatis-plus,shiro,springmvc,角色管理和组管理,非常简单实用,非常适合学习,不用输入验证码可以登录,admin密码123456

Apache Shiro实现用户登录功能

Shiro进行权限控制的四种方式 1.在程序中 通过 Subject 编程方式进行权限控制。 2. 配置 Filter 实现 URL 级别粗粒度权限控制。 3. 配置代理,基于注解实现细粒度权限控制。 4. 在页面中使用 shiro 自定义标签实现 页面显示权限控制。 实现用户登录功能 配置 shiro 的 Filter 实现 URL 级别权限控制 1.配置 web.xml。 <fi...

wunianisme的博客 2386

利用NURBS曲线进行点云曲面拟合算法

点云拟合曲面算法是将点云数据拟合成一个二次或高次曲面模型的算法。这种算法主要用于三维模型重建、计算机视觉、机器人感知、医学图像处理等领域。最小二乘法(Least Squares Method):通过最小化点到曲面距离的平方和来拟合曲面模型。三角剖分算法(Triangulation-Based Method):将点云构建成三角网格,再拟合成曲面模型。隐式曲面算法(Implicit Surface Method):通过定义一个隐式函数来表示曲面,然后用点云数据来估计隐式函数的系数。

weixin_44770969的博客 1万+

Springboot+Shiro实现登录

Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。shiro由三部分组成:1、Subject:当前操作的用户就是当前登录的用户;2、SecurityMapper:该组件用来管理所有操作用户的安全操作3、Realm:该组件需要自己来定义,shiro当前登录的账号、密码是否正确,并且其拥有那些权限。

gnsbxjj的博客 1034

OpenFOAM-v2006重叠网格挖洞问题实战:如何手动修复overset代码中的边缘识别缺陷

本文深入探讨了OpenFOAM-v2006中重叠网格挖洞问题的实战解决方案,重点修复overset代码中的边缘识别缺陷。通过逆向工程解析挖洞决策机制,设计最小侵入式的函数override方案,并建立多级验证体系,有效解决了网格挖洞区域覆盖不全的问题,提升了计算流体动力学模拟的准确性和可靠性。

weixin_29216049的博客 430

COMSOL相场法模拟枝晶生长:溶质偏析模型搭建全流程

凝固过程中枝晶形貌与溶质偏析直接决定铸件微观组织与力学性能,是材料加工领域长期关注的核心问题。相场法凭借弥散界面描述天然处理拓扑演化,成为模拟枝晶生长的主流数值方法,而通用有限元平台COMSOL为自定义偏微分方程求解提供了高度灵活的实现路径。从热力学驱动、界面各向异性到溶质再分配,模型需准确耦合相场方程与浓度扩散方程,才能在二元合金凝固模拟中还原真实枝晶尖端速度、二次臂形貌及界面富集行为。围绕溶质偏析这一关键变量,建模过程涉及无量纲化参数标定、反溶质截留项配置、分离式求解器与网格各向异性控制等核心细节。该方

weixin_30402231的博客 308

使用shiro实现认证登录

登录的controller从页面输入的数据到这里来进行验证,subject.login()登录方法需要一个安全管理器UsernamePasswordToken将用户名和密码交给安全管理器进行验证是否正确如果用户名密码不存在就会抛出异常我们通过捕获异常来给出相应的提示。MyRealm接受用户的信息判断是否存在,如果用户名或密码错误则抛出相应的异常到调用他的controller的异常捕获后给出相应的提示。在service接口中定义一个登录的查询方法。

2403_86834756的博客 617

LMX2594时钟配置实战:TICS PRO从入门到寄存器导出

本文详细介绍了LMX2594时钟芯片的配置实战,重点讲解了如何使用TICS PRO调试软件简化复杂的寄存器设置过程。通过实例演示从基础频率配置到高级参数调优的全流程,并分享SPI写入的嵌入式系统移植技巧,帮助工程师快速掌握高性能时钟芯片的配置方法。

weixin_29189003的博客 551

Shiro+JWT实现用户登陆认证,权限控制

shiro用来认证用户及权限控制,jwt用来生成一个token,暂存用户信息。为什么不使用session而使用jwt?传统情况下是只有一个服务器,用户登陆后将一些信息以session的形式存储服务器上,然后将sessionid存储在本地cookie中,当用户下次请求时将会将sessionid传递给服务器,用于确认身份。但如果是分布式的情况下会出现问题,在服务器集群中,需要一个sess...

我的博客 1万+

人大金仓数据库Kingbase FlySync同步程序安装

Kingbase FlySync同步程序(以下简称 KFS)是面向异地容灾、数据集中共享的场景推出的具备在异构数据平台间实现实时、增量数据同步的工具类产品,主要采用了物理日志解析技术,帮助用户解决不同数据平台的数据间可实现任意方向实时移动流转的问题,并保证此过程中数据不丢失,状态可监控,流转数据量可统计。KFS 需要安装的主要组件有 2 个,分别是后端同步程序和管理控制平台,另外KFS的部署方式也有2种,为分离部署何集中部署•集中部署:KFS与数据库部署在同一机器上。

weixin_44312518的博客 1178

Xilinx HydraMini试玩教程

HydraMini是Xilinx推出的基于Pynq-Z2开发板的自动驾驶开发小车,其有着简单易学、高灵活性、高扩展性、高性能等优良特性,是研究人员和学生进入自动驾驶领域的一个平台。本教程会通过最基础的讲解和步骤带领读者熟悉这个平台的基本开发流程。

qq_25762163的博客 1772

shiro基本使用和完成登录

Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 就足够了。对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了。

qq_48655035的博客 1408

hwasan实例分析踩内存之一:camx进程stack tag-mismatch的三种解决方案

hwasan实例分析踩内存之一:camx进程stack tag-mismatch的三种解决方案。

1291

Shiro实现用户认证和授权

文章目录1. Shiro认证1. Shiro认证流程源码分析2. 自定义Realm3. md5+salt密码加盐认证2. Shiro授权 1. Shiro认证 1. Shiro认证流程源码分析 主体(subject)需要携带身份信息和凭证信息,shiro在认证时会将这些信息打包成一个令牌,进入到安全管理器中进行认证。 public class TestAuthenticator { public static void main(String[] args) { //1.创建安全

你今天真好看呀 1590

实战:RK3568 Android14 调试 MIPI DSI 液晶屏

LCD1_RST -> 对应原理图网络连接到 GPIO。LCD1_PWR_EN ->用于给屏幕 VCC 供电。LCD0_BL_EN / LCD0_BL_PWM -> MP3302 升压芯片驱动 LED 灯条。![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/100f2be7f763494da1032464e272e63b.png&pinctrl {/* 配置 LCD_RST 和 LCD_EN */

qq_33427070的博客 1548

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

shiro权限

一、权限框架介绍 1.什么说权限框架? 权限说简单点就是我们字面理解的意思,项目中,例如普通用户和超级管理园 权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。 1.1 用户身份认证 身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件K

天地无名 1749

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

IDEA中接受数据并在数据库表中匹配用户名和密码(不用依赖包实现,底层)

若记不住,其实用心去理解会更容易,甚至不用记效果更好,首先明确我们的目的,第一拿到数据库数据,第二在idea中需要有对象去执行我要实现的匹配功能;从这大概的两步骤。就能分析出整个步骤 。第一怎么拿到数据?通过连接也就是getConnection(),第二怎么去执行匹配呢?通过数据库操作对象去执行呀,也就是preparedStatement(此执行对象是通过连接获取)拿到执行对象后他的参数需要传入一个sql语句;在sql语句中需要去填充占位符吧?那就调用他的setObject()方法,注意这里占位符下标是从1

qq_45043813的博客 1411

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

使用Shiro 实现登录

项目的目录结构 1、login.jsp <script type="text/javascript"> function doLogin(){ var username = $("#username").val(); var password = $("#password").val(); $.ajax({ type: "POST", url: "login",

m0_67392661的博客 1330

【Shiro】SimpleAuthorizationInfo如何授权

本文基于上一篇文章进行介绍【Shiro】SimpleAuthenticationInfo如何验证password。经过上一篇文章的探求,这回直接找准方法;我们回过头看下ShiroRealm,它继承了AuthorizingRealm。

kevin的博客 1398

shiro身份验证授权入门

一、 介绍: shiro是apache提供的强大而灵活的开源安全框架,它主要用来处理身份认证,授权,企业会话管理和加密。 shiro功能:用户验证、用户执行访问权限控制、在任何环境下使用session API,如cs程序。可以使用多数据源如同时使用oracle、mysql。单点登录(sso)支持。remember me服务。详细介绍还请看官网的使用手册:http://shiro.apache.org/reference.html 与spring security区别,个人觉得二者的主要区别是: 1、shir

fwdwqdwq的博客 638

Shiro 权限验证原理

Shiro 权限验证原理

PinkCoder 2703

Shiro的学习

Shiro的学习

m0_63224330的博客 1057

shiro授权SSM

shiro授权SSM 授权 1.添加角色和权限的授权方法 //根据username查询该用户的所有角色,用于角色验证 Set findRoles(String username); //根据username查询他所拥有的权限信息,用于权限判断 Set findPermissions(String username); 在ShiroUserMapper.xml中新增内容: <select id...

hao_dream_xi的博客 321

shiro 详解

shiro笔记 梦想只要能持久,就能成为现实。我们不就是生活在梦想中的吗? ——丁尼生 最近研究了一下 shiro   分享一下我对shiro 的理解. Apache shiro 是一个 java 的安全的框架  相当简单 不仅可以用在 java SE 也可以用在 java EE 接下来我们分别从外部和内部来看看Shiro的架构,对于一个好的框架,从外部来

FengLoveQ的博客 1141

shiro授权流程分析

上一篇博客,写了shiro认证流程分析 ,shiro主要功能是认证和授权,接下来,看看授权是如何进行的,既然要授权,当然会执行我们自定义的授权方法,所以在授权方法打个断点看看情况,当访问需要角色或者权限的接口时,就会来到授权方法(这里暂时不考虑缓存的因素,可以看做是第一次请求): 我们看一下方法调用栈: 可以看到控制器AdminController是C...

qiuxinfa123的博客 400

Shiro学习笔记(3)——授权(Authorization)

什么是授权 授权三要素 Shiro的三种授权方式 1 编码方式授权 2 基于注解的授权 3 JSP标签授权1.什么是授权授权,就是访问控制,控制某个用户在应用程序中是否有权限做某件事2.授权三要素 权限 请看Shiro学习笔记(1)——shiro入门中权限部分内容角色 通常代表一组行为或职责.这些行为演化为你在一个软件应用中能或者不能做的事情。角色通常是分配给用户帐户的,因此,通过分配,用户

君君的专栏 2万+
上一篇: springboot +秒嘀 实现短信发送
下一篇: 类.class.classLoader.getResource(..)的基本认识(一)
25k董
博客等级 码龄9年 5粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值