springboot集成shiro实现注册、登录、退出功能
生活随笔
收集整理的這篇文章主要介紹了
springboot集成shiro实现注册、登录、退出功能
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Shiro中的認證對象
- Subject 主體
訪問系統的用戶。主體可以是用戶、程序等,進行認證的都稱為主體。
- Principal 身份信息
是主體進行身份認證的標識,標識具有唯一性,如用戶名、手機號、郵箱等,一個主體可以有多個身份,但必須有一個主身份。
- Credential 憑證信息
是只有主體自己知道的安全信息,如密碼、證書等。
Shiro的認證過程
首先主體需要攜帶身份信息和憑證信息,比如用戶名和密碼,然后Shiro會將這些信息包裝成一個令牌,也就是Token,然后再通過Shiro中的安全管理器進行認證。安全管理器再調用認證器,認證器再去調用Realm獲取數據。將攜帶的身份信息和憑證信息與原始數據進行比對,如果一致的話就會進入應用也就是登錄認證成功。
Shiro配置(重點)
引入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.創建ShiroFilter 負責攔截所有請求@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//給ShiroFilter設置安全管理器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//配置系統受限和認證資源Map<String,String> map = new HashMap<String,String>();map.put("/user/addUser","authc");//authc 請求這個資源需要認證和授權map.put("/user/loadAllUserList","authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//配置認證界面 當需要進行認證時會跳到下面的login.jsp頁面。shiroFilterFactoryBean.setLoginUrl("/WEB_INF/jsp/login.jsp");return shiroFilterFactoryBean;}//2.創建安全管理器@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();//給安全管理器設置RealmdefaultWebSecurityManager.setRealm(realm);return defaultWebSecurityManager;}//3.創建Realm@Beanpublic Realm getRealm(){UserRealm userRealm = new UserRealm();//修改憑證匹配器HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();//設置加密算法為MD5hashedCredentialsMatcher.setHashAlgorithmName("MD5");//設置散列次數hashedCredentialsMatcher.setHashIterations(1024);userRealm.setCredentialsMatcher(hashedCredentialsMatcher);return userRealm;} }創建自定義的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;//自動以Realm public class UserRealm extends AuthorizingRealm {@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//根據身份信息String principal = (String) authenticationToken.getPrincipal();//在工廠中獲取bean對象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;} }生成隨機鹽配置
package boc.ljh.utils;import java.util.Random;public class SaltUtils {//生成隨機鹽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對象*/ @Component public class ApplicationContextUtils implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}//根據bean名字獲取工廠中指定的bean對象public static Object getBean(String beanName){return context.getBean(beanName);} }實現用戶注冊功能(注冊時對密碼進行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("用戶注冊")@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("注冊成功");result.setStatus(200);}else{result.setMessage("注冊失敗");result.setStatus(500);}return result;}}dao
//用戶注冊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
//用戶注冊Integer registerUserInfo(User user);serviceImpl
@Overridepublic Integer registerUserInfo(User user) {//1.生成隨機鹽String salt = SaltUtils.getSalt(8);//2.將隨機鹽保存到數據庫user.setUserSalt(salt);//明文密碼進行MD5+隨機鹽+hash散列處理Md5Hash md5Hash = new Md5Hash(user.getUserPassword(),salt,1024);user.setUserPassword(md5Hash.toHex());Integer num = userDao.registerUserInfo(user);return num;}實現用戶登錄功能
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
//根據用戶名獲取用戶信息User loadUserInfoByUsername(String usename);mapper.xml
<select id="loadUserInfoByUsername" resultMap="BaseResultMap">service
//根據用戶名獲取用戶信息User loadUserInfoByUsername(String usename);serviceImpl
@Overridepublic User loadUserInfoByUsername(String usename) {return userDao.loadUserInfoByUsername(usename);}實現用戶退出功能
controller
@ApiOperation("用戶退出")@PostMapping("/loginout")public Result loginout(){Result result = new Result();Subject subject = SecurityUtils.getSubject();subject.logout();result.setStatus(200);result.setMessage("退出成功");return result;}總結
以上是生活随笔為你收集整理的springboot集成shiro实现注册、登录、退出功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mybatis实现分页查询-自己封装分页
- 下一篇: ApiOperationSupport注