springboot集成shiro实现注册、登录、退出功能
生活随笔
收集整理的這篇文章主要介紹了
springboot集成shiro实现注册、登录、退出功能
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Shiro中的認(rèn)證對(duì)象
- Subject 主體
訪問系統(tǒng)的用戶。主體可以是用戶、程序等,進(jìn)行認(rèn)證的都稱為主體。
- Principal 身份信息
是主體進(jìn)行身份認(rèn)證的標(biāo)識(shí),標(biāo)識(shí)具有唯一性,如用戶名、手機(jī)號(hào)、郵箱等,一個(gè)主體可以有多個(gè)身份,但必須有一個(gè)主身份。
- Credential 憑證信息
是只有主體自己知道的安全信息,如密碼、證書等。
Shiro的認(rèn)證過程
首先主體需要攜帶身份信息和憑證信息,比如用戶名和密碼,然后Shiro會(huì)將這些信息包裝成一個(gè)令牌,也就是Token,然后再通過Shiro中的安全管理器進(jìn)行認(rèn)證。安全管理器再調(diào)用認(rèn)證器,認(rèn)證器再去調(diào)用Realm獲取數(shù)據(jù)。將攜帶的身份信息和憑證信息與原始數(shù)據(jù)進(jìn)行比對(duì),如果一致的話就會(huì)進(jìn)入應(yīng)用也就是登錄認(rèn)證成功。
Shiro配置(重點(diǎn))
引入Shiro依賴
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.1</version></dependency>配置ShiroConfig
package boc.ljh.config;import boc.ljh.config.shiro.realm.UserRealm; import boc.ljh.pojo.User; import org.apache.logging.log4j.message.StringFormattedMessage; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.HashMap; import java.util.Map;@Configuration public class ShiroConfig {//1.創(chuàng)建ShiroFilter 負(fù)責(zé)攔截所有請(qǐng)求@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//給ShiroFilter設(shè)置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//配置系統(tǒng)受限和認(rèn)證資源Map<String,String> map = new HashMap<String,String>();map.put("/user/addUser","authc");//authc 請(qǐng)求這個(gè)資源需要認(rèn)證和授權(quán)map.put("/user/loadAllUserList","authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//配置認(rèn)證界面 當(dāng)需要進(jìn)行認(rèn)證時(shí)會(huì)跳到下面的login.jsp頁面。shiroFilterFactoryBean.setLoginUrl("/WEB_INF/jsp/login.jsp");return shiroFilterFactoryBean;}//2.創(chuàng)建安全管理器@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//給安全管理器設(shè)置RealmdefaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3.創(chuàng)建Realm@Beanpublic Realm getRealm(){UserRealm userRealm = new UserRealm();//修改憑證匹配器HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();//設(shè)置加密算法為MD5hashedCredentialsMatcher.setHashAlgorithmName("MD5");//設(shè)置散列次數(shù)hashedCredentialsMatcher.setHashIterations(1024);userRealm.setCredentialsMatcher(hashedCredentialsMatcher);return userRealm;} }創(chuàng)建自定義的Realm
package boc.ljh.config.shiro.realm;import boc.ljh.pojo.User; import boc.ljh.service.UserService; import boc.ljh.utils.ApplicationContextUtils; 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.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.util.ObjectUtils;//自動(dòng)以Realm public class UserRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//根據(jù)身份信息String principal = (String) authenticationToken.getPrincipal();//在工廠中獲取bean對(duì)象UserService userService = (UserService) ApplicationContextUtils.getBean("userServiceImpl");User user = userService.loadUserInfoByUsername(principal);if(!ObjectUtils.isEmpty(user)){return new SimpleAuthenticationInfo(user.getUserName(),user.getUserPassword(), ByteSource.Util.bytes(user.getUserSalt()),this.getName());}return null;} }生成隨機(jī)鹽配置
package boc.ljh.utils;import java.util.Random;public class SaltUtils {//生成隨機(jī)鹽public static String getSalt(int num){char[] chars = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz!@#$%^&*()_+-={}[],./;:\"'\\".toCharArray();StringBuilder stringBuilder = new StringBuilder();for (int i = 0; i <num ; i++){char aChar = chars[new Random().nextInt(chars.length)];stringBuilder.append(aChar);}return stringBuilder.toString();} }獲取工廠中bean的配置
package boc.ljh.utils;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;/*** 配置獲取工廠中bean對(duì)象*/ @Component public class ApplicationContextUtils implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}//根據(jù)bean名字獲取工廠中指定的bean對(duì)象public static Object getBean(String beanName){return context.getBean(beanName);} }實(shí)現(xiàn)用戶注冊(cè)功能(注冊(cè)時(shí)對(duì)密碼進(jìn)行MD5+salt+hash散列加密)
controller
package boc.ljh.controller;import boc.ljh.config.AppCode; import boc.ljh.config.PaginationHelper; import boc.ljh.config.Result; import boc.ljh.pojo.User; import boc.ljh.service.UserService; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import io.swagger.annotations.*; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.*;import javax.annotation.Resource; import javax.jws.soap.SOAPBinding;@Api(tags = "用戶管理") @RestController @RequestMapping("/user") public class UserController {@Resourceprivate UserService userService;@ApiOperation("用戶注冊(cè)")@PostMapping("/register")@ApiOperationSupport(ignoreParameters = {"userId","userAge","userSalt"})public Result register(@RequestBody User user){Result result = new Result();Integer num = userService.registerUserInfo(user);if(num == 1){result.setMessage("注冊(cè)成功");result.setStatus(200);}else{result.setMessage("注冊(cè)失敗");result.setStatus(500);}return result;}}dao
//用戶注冊(cè)Integer registerUserInfo(User user);mapper.xml
<insert id="registerUserInfo" parameterType="boc.ljh.pojo.User">insert into user(user_name, user_password,user_salt) values (#{userName},#{userPassword},#{userSalt});</insert>service
//用戶注冊(cè)Integer registerUserInfo(User user);serviceImpl
@Overridepublic Integer registerUserInfo(User user) {//1.生成隨機(jī)鹽String salt = SaltUtils.getSalt(8);//2.將隨機(jī)鹽保存到數(shù)據(jù)庫user.setUserSalt(salt);//明文密碼進(jìn)行MD5+隨機(jī)鹽+hash散列處理Md5Hash md5Hash = new Md5Hash(user.getUserPassword(),salt,1024);user.setUserPassword(md5Hash.toHex());Integer num = userDao.registerUserInfo(user);return num;}實(shí)現(xiàn)用戶登錄功能
controller
@ApiOperation("用戶登錄")@PostMapping("/login")@ApiOperationSupport(ignoreParameters = {"userAge","userId","userSalt"})public Result login(@RequestBody User user){Result result = new Result();Subject subject = SecurityUtils.getSubject();try {subject.login(new UsernamePasswordToken(user.getUserName(),user.getUserPassword()));result.setMessage(AppCode.LOGIN_SUCCESS.message);result.setStatus(AppCode.LOGIN_SUCCESS.code);return result;}catch (UnsupportedOperationException e) {result.setMessage(AppCode.LOGIN_NAME_FALL.message);result.setStatus(AppCode.LOGIN_NAME_FALL.code);return result;}catch (IncorrectCredentialsException e){result.setMessage(AppCode.LOGIN_PASS_FALL.message);result.setStatus(AppCode.LOGIN_PASS_FALL.code);return result;}}dao
//根據(jù)用戶名獲取用戶信息User loadUserInfoByUsername(String usename);mapper.xml
<select id="loadUserInfoByUsername" resultMap="BaseResultMap">service
//根據(jù)用戶名獲取用戶信息User loadUserInfoByUsername(String usename);serviceImpl
@Overridepublic User loadUserInfoByUsername(String usename) {return userDao.loadUserInfoByUsername(usename);}實(shí)現(xiàn)用戶退出功能
controller
@ApiOperation("用戶退出")@PostMapping("/loginout")public Result loginout(){Result result = new Result();Subject subject = SecurityUtils.getSubject();subject.logout();result.setStatus(200);result.setMessage("退出成功");return result;}總結(jié)
以上是生活随笔為你收集整理的springboot集成shiro实现注册、登录、退出功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mybatis实现分页查询-自己封装分页
- 下一篇: ApiOperationSupport注