用户登录功能实现(shiro)

Posted javajava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用户登录功能实现(shiro)相关的知识,希望对你有一定的参考价值。

一  配置shiro的filter实现URL级别权限控制  

shiro的工作流程:application code(代码)--->Subject--->SecurityManager--->Realm---->SecurityManager(底层判断)---->Suject--->application code

1.配置web.xml

技术分享图片
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <!-- spring配置文件位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- spring核心监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
<!-- 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>

    <!-- struts2 过滤器 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
</web-app>
View Code

2.配置application.xml    

anon 未认证可以访问   authc 认证后可以访问     perms 需要特定权限才能访问     roles 需要特定角色才能访问

user 需要特定用户才能访问    port 需要特定端口才能访问    reset 根据指定 HTTP 请求访问才能访问

技术分享图片
<?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  <!-- 登录时在认证前访问 -->
                /validatecode.jsp*=anon  <!-- anon 未认证可访问.authc认证后可访问-->
                /css/**=anon
                /js/**=anon
                /images/**=anon
                /services/**=anon
                /**=authc
            </value>
        </property>
    </bean>
        <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"></property>
    </bean>
    <!-- shiro的后处理器 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor">
    
    </bean>
</beans>
View Code

3.在登录界面,form表单补全,并提交.

<form class="form-horizontal" id="loginform" name="loginform" method="post" action="user_login.action">
<a href="javascript:$(‘#loginform‘).submit();" id="loginform" name="loginform" >立即登录</a>

4.在UserAction编写login方法

技术分享图片
package cn.itcast.bos.web.action.system;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.web.action.common.BaseAction;
@Namespace("/")
@Controller
@ParentPackage("json-default")
@Scope("prototype")
public class UserAction extends BaseAction<User>{
    @Action(value="user_login",results={@Result(type="redirect",name="success",location="index.html")
    ,@Result(name="login",type="redirect",location="login.html")})
    public String login(){
        //用户名和密码都保存在model中
        //基于shiro实现登录
        Subject subject =  SecurityUtils.getSubject();
        //用户名和密码保存到token中
        AuthenticationToken token= new UsernamePasswordToken(model.getUsername(),model.getPassword());
        try {
            //如果正常登录,表示没有异常.登陆成功
            subject.login(token);
            return SUCCESS;
        } catch (Exception e) {
            //如果异常,表示登录失败,重新跳转到登录页面
            e.printStackTrace();
            return LOGIN;
        }
    }
}
View Code

5.定义Realm,实现认证方法.   

技术分享图片
package cn.itcast.bos.realm;

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.stereotype.Component;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
//加入Spring管理的注解,bean管理.
@Component("bosRealm")
public class BosRealm extends AuthorizingRealm{
   private UserService  userService ;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        System.out.println("授权...");
        return null;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证...");
        //转换token
        UsernamePasswordToken UsernamePasswordToken=(UsernamePasswordToken) token;
        //根据用户名查询用户信息
        User user = userService.findByUsername(UsernamePasswordToken.getUsername());
        if(user==null){
            //用户名不存在
            //参数一:期望登陆后保存在subject中的信息
            //参数二:密码
            //参数三:realm的名称
            //return new SimpleAuthenticationInfo(user,null,getName());
            return null;
        }else{
            //用户名存在
            //当返回密码时,securityManager安全管理器会自动比较与用户传过来的密码
            //如果一致,登陆成功,如果不一致,报密码错误异常
            return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
        }
        
    }

}
View Code

6.调用service与dao

package cn.itcast.bos.service.system;

import cn.itcast.bos.domain.system.User;

public interface UserService {

    public User findByUsername(String username);
}
package cn.itcast.bos.service.system.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bos.dao.system.UserRepository;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
@Service
@Transactional
public class UserServiceImpl implements UserService {
    private UserRepository userRepository ;
    @Override
    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

}
package cn.itcast.bos.dao.system;

import org.springframework.data.jpa.repository.JpaRepository;

import cn.itcast.bos.domain.system.User;

public interface UserRepository extends JpaRepository<User, Integer>{

    public User findByUsername(String username);
    
}

org.apache.shiro.authc.UnknownAccountException 当认证方法直接返回 null,说明用户名不存在

org.apache.shiro.authc.IncorrectCredentialsException 当返回对象中密码与用户输入密码不一致 密码错误

 







以上是关于用户登录功能实现(shiro)的主要内容,如果未能解决你的问题,请参考以下文章

Shiro实现登录功能的流程及配置

springboot集成shiro实现用户登录认证

Shiro安全框架——快速入门登录拦截用户认证请求授权

shiro实现不同用户多realm登录

Shiro原理流程,代码示例

Shiro原理流程,代码示例