springboot integration shiro user login for authentication, authorization

Foreword

Log function is achieved through the integration of shiro.

shiro has three core components: Subject, SecurityManager and Realms.

  • Subject : represents the current user's security operation, SecurityManager manage all users of the security operation.

  • The SecurityManager : It is the core framework of Shiro, a typical Facade pattern, Shiro to manage the internal component instance by SecurityManager, and through it to provide a variety of services security management.
    ( Facade模式: By providing a consistent interface to a number of complex subsystems, these subsystems easier the access mode is the mode of foreign there is a unified interface, external applications without concern for internal subsystem specific. detail.)

  • Realm : Realm act as a "bridge" or "connector" between Shiro and application security data. That is, when a user performs an authentication (login) and authorization (access control) verification, Shiro looks for information from users and their privileges in the application configuration Realm.

Note: In the following steps, we will achieve the first certification major, the last increase in resources authorized function on the basis of certification

First, the introduction of dependence

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
</dependency>

Second, write UserRealm class (certified only)

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;//用于mybatis查询数据库用户信息的服务层

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        String username=token.getUsername();
        User userByName = userService.findUserByName(username);
        //如果用户根本不存在
        if(userByName==null)
        {
            return null;  //如果返回null,会抛出UnknownAccountException
        }
        //将真正的密码给到shiro 他会自动帮我们处理
        return  new SimpleAuthenticationInfo("",userByName.getPassword(),"");


    }
}

Note that, in the above, if the user does not exist, we return directly to null, shiro will automatically throw UnknownAccountException; if the user exists but the password will throw error IncorrectCredentialsException, the correct password no exception is thrown.

As these two exceptions thrown what use is it, we later say.

Third, create shiroConfig configuration class (authentication only)

@Configuration
public class shiroConfig {
    /**
     * 创建ShiroFilterFactoryBean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager)
    {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //添加shiro内置过滤器
        //常用的过滤器
        //anon  无需认证
        //authc 必须认证才可以访问
        //user  如果使用rememberme 的功能可以直接访问
        //perms 该资源必须授权资源权限才可以访问
        //role 必须得到角色权限才可以访问
        Map<String,String> filterMap = new LinkedHashMap<String,String>();

		//这里将add和update这种操作拦截
        filterMap.put("/html/addUserShiro.html","authc");
        filterMap.put("/html/updateUserShiro.html","authc");

        //设置拒绝后返回页面
        shiroFilterFactoryBean.setLoginUrl("/html/loginShiro.html");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        return shiroFilterFactoryBean;

    }
    /**
     * 创建DefaultWebSecurityManager
     */
    @Bean(name ="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm)
    {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

        defaultWebSecurityManager.setRealm(userRealm);

        return defaultWebSecurityManager;
    }


    /**
     * 创建realm
     */
    @Bean(name ="userRealm") //使用Bean注解:方法返回的对象给spring管理
    public UserRealm getUserRealm()
    {
        return new UserRealm();
    }

}

Fourth, easy test writing Controller

   @RequestMapping(value="/loginShiro" )
    @ResponseBody
    public  RespBean loginShiro(HttpServletRequest httpServletRequest) throws IOException {
        String username=httpServletRequest.getParameter("username");
        String pwd=httpServletRequest.getParameter("password");
        //1. 获取subject
        Subject subject = SecurityUtils.getSubject();
        //2. 封装用户数据
        UsernamePasswordToken token=new UsernamePasswordToken(username,pwd);
        //3.执行登录判断
        try {
            subject.login(token);
            return RespBean.ok("success");
        }catch (UnknownAccountException e)
        {
            return RespBean.error("账户不存在!");
        }catch (IncorrectCredentialsException e)
        {
            return RespBean.error("密码错误!");
        }

    }

Since shiro will throw depending on the circumstances UnknownAccountExceptionand IncorrectCredentialsExceptionabnormal, we can capture the above controller.

Five simple test performed postman Login

We postman test url login, database pre-stored user names and passwords are wuyuehang user information.

When the login account password are correct
Here Insert Picture Description
this time the controller does not throw an exception, so the successful landing.

When the logged-on user does not exist, we return directly in front of the null, shiro will throw UnknownAccountExceptionan exception, which is caught controller, return the account information does not exist.
Here Insert Picture Description
When the wrong password, the password is to shiro, shiro found wrong password, throws IncorrectCredentialsExceptionan exception, it is caught in the controller in order to return the password error message.
Here Insert Picture Description
This is a combination shiro and login.

Sixth, the actual certification testing

Next, we will test a function like this:

  1. If direct access authc type of interface, because the certification will not automatically jump to the login screen.
  2. After login, authenticated, you can access authc interface

We shiroConfig class, on "/html/addUserShiro.html"and "/html/updateUserShiro.html"two paths to intercept and designate the two paths that must be properly authenticated before access. Let's test it

  1. First direct access "/html/addUserShiro.html", because no certification, we will automatically jump to set a good"/html/loginShiro.html"
    Here Insert Picture Description

  2. Jump to log in on the login screen, the login is successful we will jump to a test interface
    Here Insert Picture Description
    of these two hyperlinks respectively in front of us set authc, the need to intercept the authentication interface.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>查询成绩</title>
</head>
<body>
  <a href="/html/addUserShiro.html">add</a>
  <a href="/html/updateUserShiro.html">update</a>

</body>
</html>

After just a click, we can see that after the login authentication, we came in.
Here Insert Picture Description

At this point, the user authentication (ie login is successful) after, before they can access a blocked interface.

Next, let's implement authorized to operate shiro, authorization application scenarios that although some users authenticated, but we still have to be controlled authority.

Seven authorization settings

And certification, we first need to do is set up interceptors to resource authorization perms, for example, we added resources authorized interception,

filterMap added shiroconfig class

 filterMap.put("/html/addUserShiro.html","perms[user_add]");

user_add any given string, but here is what is behind the string will need.

Then, after we complete the certification by logging in, then click on /html/addUserShiro.htmlthis path, the following interface will appear, after previously authenticated access to resources interface will not work.
Here Insert Picture Description
The reason is: Unauthorized, likewise, we also can customize a unauthorized html interface, as shown below

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>拒绝访问</title>
</head>
<body>
    <h1>您好,您没有访问该界面的权限!</h1>
</body>
</html>

Add shiroconfig class

 shiroFilterFactoryBean.setUnauthorizedUrl("/html/Unauthorized.html");

Test again
Here Insert Picture Description
logic code we write authorization in the next doGetAuthorizationInfo method UserRealm class

 //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addStringPermission("user_add");
        
        return info;
    }

In this way, we completed the authorized resources, to run some tests
Here Insert Picture Description
after certification, the original can not be accessed after the resource is authorized to access resources html success.

Published 200 original articles · won praise 99 · views 40000 +

Guess you like

Origin blog.csdn.net/weixin_43889841/article/details/104010997