Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Apache Shiro Security Framework in Java

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article will explain in detail how to use the Apache Shiro security framework in Java. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

1. Brief introduction to Shiro:

Apache Shiro is a security (permissions) framework for Java.

Shiro can easily develop good enough applications, which can be used not only in JavaSE environment, but also in JavaEE environment. Shiro can complete, authentication, authorization, encryption, session management, Web integration, caching and so on.

Shiro function:

Authentication: authenticate, log in, and verify whether the user has the appropriate identity

Authorization: authorization, that is, authority verification, verifies whether an authenticated user has a certain permission, that is, to determine what a user can do, such as verifying whether a user has a role, or fine-grained verification of whether a user has a right on a resource!

Session Manager: session management, that is, the first session is after the user logs in, and all its information is in the session before exiting. The session can be a normal JavaSE environment or a Web environment.

Cryptography: encryption to protect the security of data, such as password encrypted storage in the database instead of plaintext storage; Web Support: Web support, which can be easily integrated into the Web environment

Caching: cache, for example, after a user logs in, his or her user information, roles and permissions do not have to be checked every time, which can improve efficiency

Concurrency: Shiro supports concurrent verification of multithreaded applications, that is, if you start another thread in one thread, permissions can be propagated automatically.

Testing: provide testing support

Run As: allows one user to access pretending to be another user (if they allow it)

Remember Me: remember me, this is a very common feature, that is, after logging in once, you don't have to log in next time you come back.

Shiro Architecture (external)

From an external point of view, Shiro, that is, from an application perspective, observe how to use shiro to get the job done:

Subject: the object that the application code interacts with directly is Subject, that is to say, the external API core of Shiro is that Subject,Subject represents the current user. This user is not necessarily a specific person. Everything that interacts with the current application is Subject, such as web crawlers, robots, etc. All interactions with Subject will be entrusted to SecurityManager; Subject as a facade, and SecurityManageer is the actual executor.

SecurityManager: the security manager, that is, all security-related operations interact with SercurityManager, and it manages all Subject. You can see that it is the core of Shiro. It is responsible for interacting with other components of Shiro, which is equivalent to SpringMVC's.

The role of DispatcherServlet

Realm: Shiro obtains security data (such as users, roles, permissions) from Realm, that is, if SecurityManager wants to verify the identity of a user, it needs to obtain the corresponding user from Realm for comparison to determine whether the user's identity is legitimate; it also needs to get the corresponding roles and permissions of the user from Realm to verify whether the user's operation can be carried out. Realm can be regarded as DataSource.

Shiro Architecture (Internal)

Subject: any 'user' who can interact with the application

Security Manager: the DispatcherServlet; in SpringMVC is the heart of Shiro. All specific interactions are controlled by Security Manager. It manages all Subject and is responsible for authentication, authorization, session, and cache management.

Authenticator: responsible for Subject authentication, which is an extension point and can be customized. Authentication policy (AuthenticationStrategy) can be used, that is, when the user's authentication is passed.

Authorizer: the authorizer, or access controller, is used to determine whether the principal has the authority to operate accordingly, that is, to control which functions the user can access in the application.

Realm: there can be one or more realm, which can be considered as a secure entity data source, that is, it can be used to obtain a security entity, it can be implemented in DBC, it can be implemented in memory, and so on, which is provided by the user. Therefore, you generally need to implement your own realm in an application.

SessionManager: a component that manages the life cycle of Session, while Shiro can be used not only in Web environments, but also in ordinary JavaSE environments

CacheManager: cache controller to manage caches such as users, roles, permissions, etc. Because these data are rarely received, they can improve the performance of access.

Cryptography: password module, Shiro improves some common encryption components for password encryption, decryption, etc.

Second, getting started 1. Copy a case

1. Follow the prompts on the official website to find the Quick start case GitHub address: shiro/samples/quickstart/

two。 Create a new Maven project, delete its src directory, and make it the parent project

3. Create a new Maven module in the parent project

4. Copy dependencies in the Quick start case POM.xml file

Org.apache.shiro shiro-core 1.4.1 org.slf4j jcl-over-slf4j 1.7.29 org.slf4j slf4j-log4j12 1.7.29 log4j log4j 1.2.17

5. Copy the log4j.properties under resource in the Quick start case

6. Copy the shiro.ini file

7. Copy the Quickstart.java file

8. Run Startup Quickstart.java

two。 Analyze the code public class Quickstart {private static final transient Logger log = LoggerFactory.getLogger (Quickstart.class); public static void main (String [] args) {/ / factory mode, and generate a factory instance Factory factory = new IniSecurityManagerFactory ("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance (); SecurityUtils.setSecurityManager (securityManager) through the information in the shiro.ini configuration file / / get the current user object Subject Subject currentUser = SecurityUtils.getSubject (); / / get session Session session = currentUser.getSession (); session.setAttribute ("someKey", "aValue"); String value = (String) session.getAttribute ("someKey"); if (value.equals ("aValue")) {log.info ("Subject= > session [" + value + "]") } / / determine whether the current user is authenticated by if (! currentUser.isAuthenticated ()) {/ / Token: token, not obtained, random UsernamePasswordToken token = new UsernamePasswordToken ("lonestarr", "vespa"); token.setRememberMe (true); / / set to remember me try {currentUser.login (token) / / performed login operation} catch (UnknownAccountException uae) {/ / if the user name does not exist log.info ("There is no user with username of" + token.getPrincipal ()) } catch (IncorrectCredentialsException ice) {/ / if the password is incorrect log.info ("Password for account" + token.getPrincipal () + "was incorrect!") } catch (LockedAccountException lae) {/ / user is locked, if too many passwords are output, log.info ("The account for username" + token.getPrincipal () + "is locked.) "+" Please contact your administrator to unlock it. ");} / /. Catch more exceptions catch (AuthenticationException ae) {/ / unexpected conditions here? Error?}} / / print its identity principal (in this case, user name) log.info ("User [" + currentUser.getPrincipal () + "] logged in successfully."); / / Test if the role has if (currentUser.hasRole ("schwartz")) {log.info ("May the Schwartz be with you!") } else {log.info ("Hello, mere mortal.");} / coarse granularity, small limit range / / Test typed limits (not instance level) if (currentUser.isPermitted ("lightsaber:wield")) {log.info ("You may use a lightsaber ring. Use it wisely. ");} else {log.info (" Sorry, lightsaber rings are for schwartz masters only. ");} / / Fine granularity, wide range of limits / / instance-level permissions (very powerful) if (currentUser.isPermitted (" winnebago:drive:eagle5 ")) {log.info (" You are permitted to 'drive' the winnebago with license plate (id)' eagle5'. ") "+" Here are the keys-have fun! ");} else {log.info (" Sorry, you aren't allowed to drive the 'eagle5' winnebago! ");} / logout currentUser.logout (); / / exit System.exit (0);}} third, SpringBoot integration Shiro1. Write a test environment

1. Create a new springboot module in the parent project just now

two。 Import dependencies for SpringBoot and Shiro integration packages

Org.apache.shiro shiro-spring 1.4.1

The following is the writing of the configuration file

Three elements of Shiro

Subject user-> ShiroFilterFactoryBean

SecurityManager manages all users-> DefaultWebSecurityManager

Realm connection data

The order of object creation in the actual operation: realm-> securityManager-> subject

3. Writing a custom realm requires inheriting AuthorizingRealm

/ / Custom UserRealm extends AuthorizingRealmpublic class UserRealm extends AuthorizingRealm {/ / Authorization @ Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) {/ / print a prompt System.out.println ("Authorization method executed"); return null } / / Authentication @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException {/ / print a prompt System.out.println ("authentication method executed"); return null;}}

4. Create a new ShiroConfig profile

@ Configurationpublic class ShiroConfig {/ / ShiroFilterFactoryBean:3 @ Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean (@ Qualifier ("securityManager") DefaultWebSecurityManager defaultWebsecurityManager) {ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean (); / / set security manager bean.setSecurityManager (defaultWebsecurityManager); return bean;} / / DefaultWebSecurityManager:2 @ Bean (name= "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager (@ Qualifier ("userRealm") UserRealm userRealm) {DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager () / / close UserRealm securityManager.setRealm (userRealm); return securityManager;} / / create a realm object, which requires a custom class: 1 @ Bean (name= "userRealm") public UserRealm userRealm () {return new UserRealm ();}}

5. The test was successful!

two。 Use 1. Login intercept

Add login requests that need to be intercepted in the getShiroFilterFactoryBean method

@ Configurationpublic class ShiroConfig {/ / ShiroFilterFactoryBean:3 @ Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean (@ Qualifier ("securityManager") DefaultWebSecurityManager defaultWebsecurityManager) {ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean (); / / set the security manager bean.setSecurityManager (defaultWebsecurityManager) / / add shiro's built-in filter / * anon: no authentication required Can access authc: must be authenticated to access user: must have "remember me" feature to use perms: have permission to a resource to access role: have a role permission to access * / filterMap.put ("/ user/add", "authc") FilterMap.put ("/ user/update", "authc"); / / intercept Map filterMap=new LinkedHashMap (); filterMap.put ("/ user/*", "authc"); bean.setFilterChainDefinitionMap (filterMap); / set login request / / bean.setLoginUrl ("/ toLogin"); return bean;}

Test: click on the add link, will not jump to the add page, but jump to the login page, blocked successfully

two。 User authentication

1. Write a login method in the Controller layer

/ / login method @ RequestMapping ("/ login") public String login (String username, String password, Model model) {/ / get the current user Subject subject = SecurityUtils.getSubject (); / / encapsulate the user's login data and get the token UsernamePasswordToken token = new UsernamePasswordToken (username, password) / / login and exception handling try {/ / the method of performing user login. If there is no exception, it means OK subject.login (token); return "index";} catch (UnknownAccountException e) {/ / if the user name does not exist System.out.println ("user name does not exist") Model.addAttribute ("msg", "wrong user name"); return "login";} catch (IncorrectCredentialsException ice) {/ / if the password is wrong System.out.println ("wrong password"); model.addAttribute ("msg", "wrong password"); return "login";}

two。 test

You can see that the AuthenticationInfo method in the custom UserRealm is executed first, and then login-related operations are performed.

3. Modify the doGetAuthenticationInfo method in UserRealm

/ / Authentication @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException {/ / print a prompt System.out.println ("authentication method executed"); / / username password String name = "root"; String password = "123456"; / / get the token generated in the logged-in controller UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken through parameters / / user name authentication if (! token.getUsername () .equals (name)) {/ / return null UnKnownAccountException return null;} / / password authentication is done by Shiro. In order to avoid contact with the password / / and finally return an implementation class of the AuthenticationInfo interface, select SimpleAuthenticationInfo / / three parameters: get the authentication of the current user. Password; authentication name return new SimpleAuthenticationInfo ("", password, ");}}

4. Test, enter the wrong password

Enter the correct password to log in successfully

IV. Shiro integrates Mybatis

1. Import dependency

Mysql mysql-connector-java 8.0.19 log4j log4j 1.2.17 com.alibaba druid 1.1.12 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.1

two。 Create a new application.yml

Spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource # Spring Boot does not inject these attribute values by default Need to bind # druid data source proprietary configuration initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true # configure filters for monitoring statistics interception Stat: monitoring statistics, log4j: logging, wall: defense sql injection # if the Times allows java.lang.ClassNotFoundException: org.apache.log4j.Priority #, import log4j dependency, Maven address: https://mvnrepository.com/artifact/log4j/log4j filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true Druid.stat.slowSqlMillis=500mybatis: type-aliases-package: com.huang.pojo mapper-locations: classpath:mybatis/mapper/*.xml

3. In application.properties

Mybatis.type-aliases-package=com.longdi.pojomybatis.mapper-locations=classpath:mapper/*.xml

4. Import dependency

Org.projectlombok lombok 1.18.10 provided

5. Write User classes

@ Data@AllArgsConstructor@NoArgsConstructorpublic class User {private int id; private String name; private String pwd; private String perms;}

6. Write UserMapper

@ Repository@Mapperpublic interface UserMapper {public User queryUserByName (String name);}

7. Write UserMapper.xml

Select * from mybatis.user where name=# {name}

8.Service layer

UserService interface:

Public interface UserService {public User queryUserByName (String name);}

9. Write the interface implementation class UserServiceImpl

@ Servicepublic class UserServiceImpl implements UserService {@ Autowired UserMapper userMapper; @ Override public User queryUserByName (String name) {return userMapper.queryUserByName (name);}}

10. Testing in ShiroSpringbootApplicationTests

SpringBootTestclass ShiroSpringbootApplicationTests {@ Autowired UserServiceImpl userService; @ Test void contextLoads () {System.out.println (userService.queryUserByName ("longdi"));}}

11. Successfully connect to the database

Fifth, realize the request authorization

1. Modify in the ShiroConfig class

2.controller Jump

3. Login intercept authorization, the test is successful

4. Write authorization doGetAuthorizationInfo methods

5. Request authorization test succeeded

VI. Shiro integrates Thymeleaf

1. Import dependency

Com.github.theborakompanioni thymeleaf-extras-shiro 2.0.0

two。 Integrate ShiroDialect

3.index.html

4. test

5. Put session in the certification

6. Modify index.html

This is the end of the article on "how to use the Apache Shiro Security Framework in Java". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report