JAVA|多Realm管理基础实现

欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

欢迎加入团队圈子!与作者面对面!直接点击!

1 前言

在shiro的使用实现中,会遇到一个问题,那就是用户和管理员的分别登录认证等,首先想到的就是只创建一个user表来存,并且给他们分别赋予不同的角色权限等。而下面要说的是另一个处理办法,那就是对于不同表的用户分别创建不同的Realm。下面就来具体看一下:

2 创建Realm

在这里创建了两个Realm作为例子(StudentRealm和AdminRealm),如图2.1

                           

JAVA|多Realm管理基础实现_第1张图片

图2.1

上面展示的为AdminRealm,StudentRealm也为同理,继承AuthorizingRealm,并实现授权及认证,其中授权及认证就根据需要自行添加。

3 ShiroConfig配置

下面就是对ShiroConfig进行配置,首先就是引入这两个Realm:

@Bean(name = "studentRealm")

    public StudentRealm studentRealm() {

        return new StudentRealm();

    }

    @Bean(name = "adminRealm")

    public AdminRealm adminRealm() {

        return new AdminRealm();

    }

接着编写shiro的DefaultWebSecurityManager,创建一个List集合,存入这两个Realm。注意:存单个Realm时用的是securityManager.setRealm(),而存多个时是securityManager.setRealms():

    @Bean(name =  "DefaultWebSecurityManager")

    public  DefaultWebSecurityManager getDefaultWebSecurityManager() {

         DefaultWebSecurityManager securityManager = new  DefaultWebSecurityManager();

         List realms = new ArrayList<>();

         realms.add(studentRealm());

         realms.add(adminRealm());

         securityManager.setRealms(realms);

        return  securityManager;

    }

4 登录认证

最后就是对登录认证的编写,由于需要区分不同登录角色,所以首先就需要在前端页面加上选择的loginType,传不同的值过来,用于进行不同的认证:

JAVA|多Realm管理基础实现_第2张图片

图4.1

然后在写一个LoginToken类,继承UsernamePasswordToken,并且加入loginType的内容:

public class LoginToken extends UsernamePasswordToken {

    private String  loginType;

    public  LoginToken(final String username,

                       final String password,

                       final String loginType) {

         super(username,password);

        this.loginType =  loginType;

    }

    public String  getLoginType() {

        return  loginType;

    }

    public void  setLoginType(String loginType) {

        this.loginType =  loginType;

    }

}

最后一步就是对Controller层接口的编写,需要传id(username),password以及选择登录的角色(学生/管理员),if判断选择的是学生还是管理员,分别进行不同的认证以及页面跳转,下面是自己的一个例子,仅供参考:

@PostMapping(value = "/student_login")

    public String  Student(String id, String password, Model model, HttpSession session, String  loginType) {

        //shiro编写登录认证

        //1.获取subject

        Subject subject  = SecurityUtils.getSubject();

        //2.封装数据

        LoginToken token  = new LoginToken(String.valueOf(id), ShiroKit.md5(password, id), loginType);

        //3.执行登录方法

        try {

            subject.login(token);

            if  (loginType.equals("student")) {

                Student  student = (Student) subject.getPrincipal();

                //userrealm里传过来的用户名拿到,把学生对象信息查出来,存入session

                student  = studentService.findByStuid((String) token.getPrincipal());

                 session.setAttribute("student",student);

                return  "redirect:/question/list1";

            }

            if  (loginType.equals("admin")) {

                Admin  admin = (Admin) subject.getPrincipal();

                 session.setAttribute("admin", admin);

                return  "redirect:/question/add_question";

            }

            //有任何异常都是登录失败

        }catch  (UnknownAccountException e){

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

            return  "register_login/login";

        }catch  (IncorrectCredentialsException e){

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

            return  "register_login/login";

        }

        return  "";

    }

5 总结

这里展示的是最基本的设置,还有其他需求或漏洞还需要按实际情况及需求解决。

 

END

主  编   |   张祯悦

责  编   |   黄晓锋

 where2go 团队


   

微信号:算法与编程之美          

长按识别二维码关注我们!

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!

你可能感兴趣的:(shiro,jwt,html,javascript,login)