Shiro permission Authentication

Source: Internet
Author: User

Shiro permission Authentication
I. Core elements of permission Authentication

As the name implies, permission authentication controls who can access which resources in the application system. The core elements include permissions, roles, and users.

Permission: it is the right to operate resources. For example, to access a url, you can add, delete, modify, and query data in a module.

Role: a set of permissions. A role can contain multiple permissions. For example, an operator role can have multiple permissions to view system bills and perform checkout.

User: the corner of the subject mentioned in identity authentication.

Ii. Authorization

There are usually three shiro authorization methods:

1. Programmatic authorization: Authorization operations in code can be performed based on roles and permissions.

2. annotation-based authorization: Use annotations to authorize methods or classes, and mark the permissions and roles that can be used by these classes.

3. Jsp tag authorization: In shiro's more flexible scenarios, I think it is jsp tag authorization. Through shiro's guest, user, principal, and other tags, different access permissions can be obtained, control page information display. Removes most of the background processing logic. Convenient and easy to use. We will introduce it in detail later.

Iii. Programming authorization instance

1. Create an INI file first.

[users]java1234=123456,role1,role2jack=123,role1

This is a role authorization method. Specifically, users with the username java1234 have the right To role role1 and role role2, and jack Users have the right to role role1.

2. the java code uses hasRole and checkRole to determine whether a user has the role1 and role2 permissions.

Here, we first encapsulate some shiro initialization and preprocessing operations into an util class.

Public class ShiroUtil {public static Subject login (String configFile, String userName, String password) {// read the configuration file and initialize the SecurityManager Factory
 
  
Factory = new IniSecurityManagerFactory (configFile); // obtain the securityManager instance SecurityManager securityManager = factory. getInstance (); // bind the securityManager instance to SecurityUtilsSecurityUtils. setSecurityManager (securityManager); // obtain the currently executed user Subject currentUser = SecurityUtils. getSubject (); // Create a token, userName/password UsernamePasswordToken token = new UsernamePasswordToken (userName, password); try {// authenticate currentUser. login (token ); System. out. println ("authentication successful! ");} Catch (AuthenticationException e) {e. printStackTrace (); System. out. println (" authentication failed! ") ;}Return currentUser ;}}
 
Create a roleTest class and call the user's hasRole and checkRole methods to determine the user permissions.

Public class RoleTest {@ Testpublic void testHasRole () {Subject currentUser = ShiroUtil. login ("classpath: shiro_role.ini", "java1234", "123456"); // Subject currentUser = ShiroUtil. login ("classpath: shiro_role.ini", "jack", "123"); System. out. println (currentUser. hasRole ("role1 ")? "Role1 role": "No role1 role"); boolean [] results = currentUser. hasRoles (Arrays. asList ("role1", "role2", "role3"); System. out. println (results [0]? "There is a role named role1": "No Role named role1"); System. out. println (results [1]? "There is a role named role2": "No Role named role2"); System. out. println (results [2]? "Role3 role": "No role3 role"); System. out. println (currentUser. hasAllRoles (Arrays. asList ("role1", "role2 "))? "Role1, role2 both have": "role1, role2 are not all"); currentUser. logout () ;}@ Testpublic void testCheckRole () {Subject currentUser = ShiroUtil. login ("classpath: shiro_role.ini", "java1234", "123456"); // Subject currentUser = ShiroUtil. login ("classpath: shiro_role.ini", "jack", "123"); currentUser. checkRole ("role1"); currentUser. checkRoles (Arrays. asList ("role1", "role2"); currentUser. checkRoles ("role1", "role2", "role3"); currentUser. logout ();}}

The permission authentication method is as follows:

[users]java1234=123456,role1,role2jack=123,role1[roles]role1=user:selectrole2=user:add,user:update,user:delete

Here we add the specific operation permissions of role1 and role2 users. role1 can perform select operations. Similarly, role2 can perform addition, deletion, and modification operations. You can also call the user's permission authentication method to authenticate the user's specific operation permissions.

Public class PermissionTest {@ Testpublic void testIsPermitted () {Subject currentUser = ShiroUtil. login ("classpath: shiro_permission.ini", "java1234", "123456"); // Subject currentUser = ShiroUtil. login ("classpath: shiro_permission.ini", "jack", "123"); System. out. println (currentUser. isPermitted ("user: select ")? "User: select permission": "No user: select permission"); System. out. println (currentUser. isPermitted ("user: update ")? "User: update permission": "user: update permission not available"); boolean results [] = currentUser. isPermitted ("user: select", "user: update", "user: delete"); System. out. println (results [0]? "User: select permission": "No user: select permission"); System. out. println (results [1]? "User: update permission": "No user: update permission"); System. out. println (results [2]? "User: delete permission": "user: delete permission not available"); System. out. println (currentUser. isPermittedAll ("user: select", "user: update ")? "Two permissions are available: user: select and update.": "user: select and update are not available."); currentUser. logout () ;}@ Testpublic void testCheckPermitted () {Subject currentUser = ShiroUtil. login ("classpath: shiro_permission.ini", "java1234", "123456"); // Subject currentUser = ShiroUtil. login ("classpath: shiro_permission.ini", "jack", "123"); currentUser. checkPermission ("user: select"); currentUser. checkPermissions ("user: select", "user: update", "user: delete"); currentUser. logout ();}}

Iv. Integrate shiro with web for permission Authentication

The following describes how to use Shiro for permission authentication in java web programs.

  1. First, add shiro jar packages: shiro-web, shiro-core; commons-logging, slf4j-api, log4j; jstl, javax. servlet. jsp-api, javax. servlet-api

  2. Add the shiroFilter in web. XML and initialize the created shiro. ini configuration file.

      
           
        
         
    Org. apache. shiro. web. env. EnvironmentLoaderListener
          
          
       
           
        
         
    ShiroFilter
            
        
         
    Org. apache. shiro. web. servlet. ShiroFilter
        
       
           
        
         
    ShiroFilter
            
        
         
    /*
        
       
       

    Shiro. ini file

    [main]authc.loginUrl=/loginroles.unauthorizedUrl=/unauthorized.jspperms.unauthorizedUrl=/unauthorized.jsp[users]java1234=123456,adminjack=123,teachermarry=234json=345[roles]admin=user:*teacher=student:*[urls]/login=anon/admin=authc/student=roles[teacher]/teacher=perms["user:create"]

    3. Create login and adminservlet for direct login and forwarding to login. jsp, and admin login for authentication, and forward to succeess. jsp and error. jsp

    Public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L; @ Overrideprotected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System. out. println ("login doget"); req. getRequestDispatcher ("login. jsp "). forward (req, resp) ;}@ Overrideprotected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System. out. println ("login dopost"); String userName = req. getParameter ("userName"); String password = req. getParameter ("password"); Subject subject = SecurityUtils. getSubject (); UsernamePasswordToken token = new UsernamePasswordToken (userName, password); try {subject. login (token); resp. sendRedirect ("success. jsp ");} catch (Exception e) {e. printStackTrace (); req. setAttribute ("errorInfo", "incorrect user name or password"); req. getRequestDispatcher ("login. jsp "). forward (req, resp );}}}

    4. Configure the data source-here we will introduce two types of reaml: Text Reaml and custom JDBC reaml.

    Text Reaml configuration details and access process

    Text Reaml configuration is integrated into Shiro. in the INI file, four users are configured. java1234 has the admin role permission, jack has the teacher role permission, role admin can perform any crud operations on the user, and teacher can perform crud operations on the student; the anon here refers to the identity of a visitor when requesting/login addresses. No identity authentication is required. Identity authentication is required when requesting/admin addresses, after filtering, you are redirected to [main] and configured as/login (jsp page). Similarly, the permission authentication pages of role and perms are set as unauthorized. jsp;

    The result of the above ini configuration is that the request directly jumps to the hello page when accessing localhost: 8080/shiro/login without authentication. When accessing localhost: 8080/shiro/admin, first forward it to login. jps for authentication, enter adminServlet, and then forward it to the error or succeess page after verification. When you access the admin address again, the user login information is recorded during the first access, so you do not need to directly jump to the success page during login. When accessing localhost: 8080/shiro/student, if the login information uses json (a user without any role permissions ), the user is not authorized (because the teacher role is required to access student in the configuration) to directly jump to the page without permission. This is the configuration of using textReaml for authentication and permission verification.

    Customize JDBC Reaml configuration and access process

    Because the text Reaml information is limited after all, the configuration is relatively troublesome, so generally, applications use custom reaml, create a custom JDBC readml and demonstrate the process of combining reaml with java programs.

    Because you need to create a database (create three tables: User, role, and permission, and associate the primary and Foreign keys in turn), first introduce the database driver jar package; in shiro, in the INI file, specify that the authentication policy used by the current securityManager is custom jdbcReaml.

    [main]authc.loginUrl=/loginroles.unauthorizedUrl=/unauthorized.jspperms.unauthorizedUrl=/unauthorized.jspmyRealm=com.java.realm.MyRealmsecurityManager.realms=$myRealm[urls]/login=anon/admin*=authc/student=roles[teacher]/teacher=perms["user:create"]
    Finally, create the database connection Util class and myReaml class to call the underlying data query dao.

    /*** Database tool class ** @ author */public Class DbUtil {public Connection getCon () throws Exception {class. forName ("com. mysql. jdbc. driver "); Connection con = DriverManager. getConnection ("jdbc: mysql: // localhost: 3306/db_shiro", "root", "123456"); return con;} public void closeCon (Connection con) throws Exception {if (con! = Null) {con. close () ;}} public static void main (String [] args) {DbUtil dbUtil = new DbUtil (); try {dbUtil. getCon (); System. out. println ("database connection succeeded");} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace (); System. out. println ("database connection failed ");}}}
    MyReaml class: inherits the shiro AuthorizingReaml class and overrides two methods: authentication and permission verification. (This explains why the program automatically jumps to the logon page when the student address is accessed without being configured to log on first. Because the underlying layer encapsulates the authentication methods for all default requests first .)

    Public class MyRealm extends AuthorizingRealm {private UserDao userDao = new UserDao (); private DbUtil dbUtil = new DbUtil (); /*** grant roles and permissions to the currently logged-on user */@ Overrideprotected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principals) {String userName = (String) principals. getPrimaryPrincipal (); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo (); Connection con = null; try {con = dbUtil. g EtCon (); authorizationInfo. setRoles (userDao. getRoles (con, userName); authorizationInfo. setStringPermissions (userDao. getPermissions (con, userName);} catch (Exception e) {e. printStackTrace ();} finally {try {dbUtil. closeCon (con);} catch (Exception e) {e. printStackTrace () ;}} return authorizationInfo;}/*** verify the currently logged-on user */@ Overrideprotected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken token) thr Ows AuthenticationException {String userName = (String) token. getPrincipal (); Connection con = null; try {con = dbUtil. getCon (); User user = userDao. getByUserName (con, userName); if (user! = Null) {AuthenticationInfo authcInfo = new SimpleAuthenticationInfo (user. getUserName (), user. getPassword (), "xx"); return authcInfo;} else {return null ;}} catch (Exception e) {e. printStackTrace ();} finally {try {dbUtil. closeCon (con);} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace () ;}} return null ;}}

    These two methods encapsulate an Identity Information Entity class AuthenticationInfo and AuthorizetionInfo to return.

    First, you can obtain the user information and query the database users, permissions, and other information based on the user name for verification. The overall process is to call loginServlet before the browser accesses the address localhost: 8080/shiro/admin. when using the login method, enter the custom MyReaml class, obtain user information, and perform authentication.


    Zookeeper

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.