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 write shiro multi-authentication login code

2025-04-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

Today, I will talk to you about how to write the shiro multi-authentication login code, which may not be well understood by many people. In order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

1. First, create a new configuration class for shiroConfig shiro, as follows:

@ Configuration identifies that the class is a configuration file, and the contents of the class will be loaded at startup. The location of the configuration file must not prevent it from being in a folder outside the startup class, otherwise it will be annotated on the startup class.

@ Bean is to hand over this class to spring management

@ Configurationpublic class SpringShiroConfig {/ * @ param realms the interface set is used here to implement * @ return * / @ Bean public SecurityManager securityManager (Collection realms) {DefaultWebSecurityManager sManager = new DefaultWebSecurityManager (); sManager.setRealms (realms); return sManager;} @ Bean public ShiroFilterFactoryBean shiroFilterFactory (SecurityManager securityManager) {ShiroFilterFactoryBean sfBean = new ShiroFilterFactoryBean (); sfBean.setSecurityManager (securityManager) / / in the case of anonymous access, the location sfBean.setLoginUrl ("/ index") that cannot be accessed is accessed; / / map is defined to specify request filtering rules (which resources allow anonymous access and which must authenticate access) LinkedHashMap map = new LinkedHashMap () / / static resources allow anonymous access: "anon" static resources cannot be authorized to write all the openings under static. To open all folders under static one by one, the key of templates can be either the location of the file or the requested path map.put ("/ bower_components/**", "anon"); map.put ("/ json/**", "anon"). Map.put ("/ pages", "anon"); map.put ("/ user/userPasswordLogin", "anon"); map.put ("/ user/login", "anon"); map.put ("/ user/reg", "anon"); / / access to this path will not enter controller, but will directly block and exit here. Ask why, you want to request the process to go to map.put ("/ user/userLogout", "logout"). / / intercept all request paths except the above map.put ("/ * *", "user"); sfBean.setFilterChainDefinitionMap (map); return sfBean;} @ Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor () {return new LifecycleBeanPostProcessor ();}

two。 Write the implementation class of Realms, which is generally inherited from AuthorizingRealm (this is the implementation user name, password login). The code is as follows:

@ Servicepublic class ShioUserRealm extends AuthorizingRealm {/ / inject userdao @ Autowired private UserDao userDao; / * set credential matcher * * @ param credentialsMatcher * / @ Override public void setCredentialsMatcher (CredentialsMatcher credentialsMatcher) {/ * if MD5 salt encryption is set here, you must use HashedCredentialsMatcher to have the following two methods * / HashedCredentialsMatcher matcher = new HashedCredentialsMatcher (); / / here is to set the encryption mode matcher.setHashAlgorithmName ("MD5") / / here is the number of times to set encryption matcher.setHashIterations (2); super.setCredentialsMatcher (matcher);} / * here is the setting of authorization * @ param principalCollection * @ return * / @ Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) {return null } / * the authentication data is obtained and encapsulated by this method. The bottom layer of the system will transfer the authentication data to the authentication manager, and the authentication manager completes the authentication operation * @ param authenticationToken * @ return * @ throws AuthenticationException * / @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException {/ / first determine whether this comes from the token data: we are divided into UsernamePasswordToken (provided by shiro). ), UserPhoneToken if (! (authenticationToken instanceof UsernamePasswordToken)) {return null;} / / get the data sent by controller UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken; / / upToken.setRememberMe (true); Shirodefault is false, whether to remember my function / / username String username = upToken.getUsername () submitted here for the user; / / remove the data to name to get the user's information User user = userDao.findUserByUserName (username) / / determine whether the user if (user = = null) {throw new UnknownAccountException ();} / determine whether the user's status is disabled (database field) if (user.getState () = = 0) {throw new LockedAccountException ();} / / here is the salt value taken from the user's information, and the salt value must be converted to ByteSource before you can use ByteSource credentialsSalt = ByteSource.Util.bytes (user.getSalt ()). / / here is to give the user's information to shiro (user is the user object, user.getPassword () is the object to be encrypted, credentialsSalt is salt, getName () current object) SimpleAuthenticationInfo info = new SimpleAuthenticationInfo (user, user.getPassword (), credentialsSalt, getName ()); return info;}}

3. At this point, the user's account password can be logged in with the controller code as follows:

RequestMapping ("userPasswordLogin") @ ResponseBody public JsonResult userPasswordLogin (String username, String password) {Subject subject = SecurityUtils.getSubject (); UsernamePasswordToken token = new UsernamePasswordToken (username, password); subject.login (token); return new JsonResult ("login Ok");}

4. Now let's implement the login implementation of SMS verification code:

Write UserPhoneToken first, and I put it in the same directory as l and springShiroConfig:

@ Componentpublic class UserPhoneToken extends UsernamePasswordToken implements Serializable {private static final long serialVersionUID = 6293390033867929958L; / Mobile number private String phoneNum; / / No-parameter construction public UserPhoneToken () {} / / get the stored value @ Override public Object getPrincipal () {if (phoneNum = = null) {return getUsername ();} else {return getPhoneNum ();}} @ Override public Object getCredentials () {if (phoneNum = = null) {return getPassword ();} else {return "ok" } public UserPhoneToken (String phoneNum) {this.phoneNum = phoneNum;} public UserPhoneToken (final String userName, final String password) {super (userName, password);} public String getPhoneNum () {return phoneNum;} public void setPhoneNum (String phoneNum) {this.phoneNum = phoneNum;} @ Override public String toString () {return "PhoneToken [PhoneNum=" + phoneNum + "]";}}

4.2 while writing shiroUserPhoneRealm, the code is as follows:

@ Servicepublic class ShioUserPhoneRealm extends AuthorizingRealm {@ Autowired private UserDao userDao; @ Override public void setCredentialsMatcher (CredentialsMatcher credentialsMatcher) {/ / the new object of CredentialsMatcher here must be AllowAllCredentialsMatcher CredentialsMatcher matcher = new AllowAllCredentialsMatcher (); super.setCredentialsMatcher (matcher);} @ Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) {return null } / * the authentication data is obtained and encapsulated by this method. The bottom layer of the system will transfer the authentication data to the authentication manager, and the authentication manager completes the authentication operation * @ param authenticationToken * @ return * @ throws AuthenticationException * / @ Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException {UserPhoneToken token = null; if (authenticationToken instanceof UserPhoneToken) {token = (UserPhoneToken) authenticationToken;} else {return null } / / get the verification code that I sent to session and the mobile number String verificationCode = (String) SecurityUtils.getSubject (). GetSession (). GetAttribute ("verificationCode"); String phone = (String) SecurityUtils.getSubject (). GetSession (). GetAttribute ("phone"); / / get the data sent by controller String verificationCode1 = (String) token.getPrincipal (); / / go to the database to query the user information User user = userDao.findUserByUserPhone (phone) according to the mobile phone number. If (StringUtils.isEmpty (verificationCode)) {throw new ServiceException ("network error");} / compare mobile phone number if (! verificationCode.equals (verificationCode1)) {throw new ServiceException ("incorrect verification code");} if (user = = null) {throw new UnknownAccountException ();} if (user.getState () = = 0) {throw new LockedAccountException ();} return new SimpleAuthenticationInfo (user,phone,getName ());}}

4.3 Login verification of mobile phone number has been basically completed: the controller code is as follows:

Password is the received CAPTCHA

@ PostMapping ("verificationCodeLogin") @ ResponseBody public JsonResult verificationCodeLogin (String password) {Subject subject = SecurityUtils.getSubject (); UserPhoneToken token = new UserPhoneToken (password); subject.login (token); return new JsonResult ("login OK");}

Bug encountered during use

1.

Org.apache.shiro.authc.UnknownAccountException: Realm [cn.tedu.wxacs.service.impl.ShioUserPhoneRealm@768d8431] was unable to find account data for the submitted AuthenticationToken [org.apache.shiro.authc.UsernamePasswordToken-Zhang San, rememberMe=false].

The reason for this problem is that one of the implementation classes in Realm is not annotated. When I demonstrate here, I should add @ Service to ShiroUserRealm.

two。

Org.apache.shiro.authc.AuthenticationException: Authentication token of type [class org.apache.shiro.authc.UsernamePasswordToken] could not be authenticated by any configured realms. Please ensure that at least one realm can authenticate these tokens.

The problem here is that it should be User user = userDao.findUserByUserName (username) of my ShioUserRealm's AuthenticationInfo method; if there is a problem with this line of code, debug will find that this sentence protects the error after execution.

Reason: because the path of the mapper file corresponding to dao is not written in my application.yml file

3. The error is reported after the new SimpleAuthenticationInfo (user,phone,getName ()) of ShioUserPhoneRealm's doGetAuthenticationInfo method is due to ShioUserPhoneRealm. In this method, you do not set the object of new to AllowAllCredentialsMatcher ().

@ Override public void setCredentialsMatcher (CredentialsMatcher credentialsMatcher) {/ / the new object of CredentialsMatcher here must be AllowAllCredentialsMatcher CredentialsMatcher matcher = new AllowAllCredentialsMatcher (); super.setCredentialsMatcher (matcher);}

There are some points that need to be paid attention to in the comments. I suggest you take a look at them. If the notes are wrong, I hope you can point out or contact me in the comments.

Because my knowledge is limited, I have no problem with this method at present, and I hope you will point out what is wrong with it. Thank you!

Using version 2.2.1 of jdk8,spring boot and version 1.4.1 of shiro

After reading the above, do you have any further understanding of how to write the shiro multi-authentication login code? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

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