国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - Java教程 - SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄功能(多 Realm 認(rèn)證)

SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄功能(多 Realm 認(rèn)證)

2021-08-16 10:47風(fēng)青宇 Java教程

這篇文章主要介紹了SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄(多 Realm 認(rèn)證),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

導(dǎo)入依賴(pom.xml)

?
1
2
3
4
5
6
7
8
9
10
11
12
<!--整合Shiro安全框架-->
 <dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring</artifactId>
  <version>1.4.0</version>
 </dependency>
 <!--集成jwt實(shí)現(xiàn)token認(rèn)證-->
 <dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.2.0</version>
 </dependency>

SpringBoot 項(xiàng)目配置 config 包下創(chuàng)建 ShiroConfig 配置類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
@Configuration
public class ShiroConfig {
 
 /**
  * ShiroFilterFactoryBean
  * <p>
  * anon:無需認(rèn)證就可以訪問
  * authc:必須認(rèn)證才能訪問
  * user:必須擁有 記住我 功能才能用
  * perms:擁有對(duì)某個(gè)資源的權(quán)限能訪問
  * role:擁有某個(gè)角色權(quán)限能訪問
  */
 @Bean
 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
  ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
  // 設(shè)置安全管理器
  factoryBean.setSecurityManager(defaultWebSecurityManager);
  // 添加shiro的內(nèi)置過濾器
  Map<String, String> filterMap = new LinkedHashMap<>();
  // 放行不需要權(quán)限認(rèn)證的接口
  // 網(wǎng)站首頁
  filterMap.put("/", "anon");
  filterMap.put("/index", "anon");
  filterMap.put("/index.html", "anon");
  // 不驗(yàn)證跳轉(zhuǎn)接口
  filterMap.put("/into/**", "anon");
 
  // 需要權(quán)限認(rèn)證的接口
  // 驗(yàn)證跳轉(zhuǎn)接口
  filterMap.put("/verifyInto/**", "authc");
  
  factoryBean.setFilterChainDefinitionMap(filterMap);
 
  // 訪問沒有授權(quán)的資源
  factoryBean.setLoginUrl("redirect:/into/login");
  // 設(shè)置無權(quán)限時(shí)跳轉(zhuǎn)的url
  factoryBean.setUnauthorizedUrl("redirect:/into/login");
 
  return factoryBean;
 }
 
 /**
  * 管理shiro的生命周期
  */
 @Bean("lifecycleBeanPostProcessor")
 public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
  return new LifecycleBeanPostProcessor();
 }
 
 /**
  * 注入 密碼登錄CustomRealm
  */
 @Bean
 @DependsOn("lifecycleBeanPostProcessor")
 public UserPasswordRealm userPasswordRealm() {
  return new UserPasswordRealm();
 }
 
 /**
  * 注入 郵箱驗(yàn)證登錄EmailRealm
  */
 @Bean
 @DependsOn("lifecycleBeanPostProcessor")
 public UserEmailRealm userEmailRealm() {
  return new UserEmailRealm();
 }
 
 /**
  * 默認(rèn)安全管理器
  */
 @Bean
 public DefaultWebSecurityManager securityManager(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm, AbstractAuthenticator abstractAuthenticator) {
  DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
  List<Realm> realms = new ArrayList<>();
  realms.add(userPasswordRealm);
  realms.add(userEmailRealm);
  defaultWebSecurityManager.setRealms(realms);
  // 記住我
  defaultWebSecurityManager.setRememberMeManager(cookieRememberMeManager());
  defaultWebSecurityManager.setAuthenticator(abstractAuthenticator);
  return defaultWebSecurityManager;
 }
 
 /**
  * 認(rèn)證器 把我們的自定義驗(yàn)證加入到認(rèn)證器中
  */
 @Bean
 public AbstractAuthenticator abstractAuthenticator(UserPasswordRealm userPasswordRealm, UserEmailRealm userEmailRealm) {
  // 自定義模塊化認(rèn)證器,用于解決多realm拋出異常問題
  //開始沒用自定義異常問題,發(fā)現(xiàn)不管是賬號(hào)密碼錯(cuò)誤還是什么錯(cuò)誤
  //shiro只會(huì)拋出一個(gè)AuthenticationException異常
  ModularRealmAuthenticator authenticator = new MyCustomModularRealmAuthenticator();
  // 認(rèn)證策略:AtLeastOneSuccessfulStrategy(默認(rèn)),AllSuccessfulStrategy,F(xiàn)irstSuccessfulStrategy
  authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
  // 加入realms
  List<Realm> realms = new ArrayList<>();
  realms.add(userPasswordRealm);
  realms.add(userEmailRealm);
  authenticator.setRealms(realms);
  return authenticator;
 }
 
 /**
  * 加入shiro注解 代理生成器 切面
  */
 @Bean
 @DependsOn({"lifecycleBeanPostProcessor"})
 public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
  DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
  advisorAutoProxyCreator.setProxyTargetClass(true);
  return advisorAutoProxyCreator;
 }
 
 /**
  * 加入shiro注解 切點(diǎn)
  */
 @Bean
 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
  AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  return authorizationAttributeSourceAdvisor;
 }
 
 /**
  * 設(shè)置cookie 記住我生成cookie
  */
 @Bean
 public CookieRememberMeManager cookieRememberMeManager() {
  CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
  cookieRememberMeManager.setCookie(rememberMeCookie());
  return cookieRememberMeManager;
 }
 
 /**
  * 設(shè)置cookie有效時(shí)間
  */
 @Bean
 public SimpleCookie rememberMeCookie() {
  /*這個(gè)參數(shù)是cookie的名稱,對(duì)應(yīng)前端頁面的checkbox的name=remremberMe*/
  SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
  /*cookie的有效時(shí)間為30天,單位秒*/
  simpleCookie.setMaxAge(259200);
  return simpleCookie;
 }
 
}

創(chuàng)建自定義驗(yàn)證器 MyCustomModularRealmAuthenticator 類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyCustomModularRealmAuthenticator extends ModularRealmAuthenticator {
 
 @Override
 protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
  AuthenticationStrategy authenticationStrategy = this.getAuthenticationStrategy();
  AuthenticationInfo authenticationInfo = authenticationStrategy.beforeAllAttempts(realms, token);
 
  Iterator var5 = realms.iterator();
  while (var5.hasNext()) {
   Realm realm = (Realm) var5.next();
   authenticationInfo = authenticationStrategy.beforeAttempt(realm, token, authenticationInfo);
   if (realm.supports(token)) {
 
    AuthenticationInfo info = null;
    Throwable t = null;
 
    info = realm.getAuthenticationInfo(token);
 
    authenticationInfo = authenticationStrategy.afterAttempt(realm, token, info, authenticationInfo, t);
   }
  }
  authenticationInfo = authenticationStrategy.afterAllAttempts(token, authenticationInfo);
  return authenticationInfo;
 }
}

創(chuàng)建密碼登錄時(shí)驗(yàn)證授權(quán) UserPasswordRealm 類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@Component
public class UserPasswordRealm extends AuthorizingRealm {
 
 // 注入用戶業(yè)務(wù)
 @Autowired
 private UserMapper userMapper;
 
 /**
  * 授權(quán)
  */
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  System.out.println("————密碼授權(quán)————doGetAuthorizationInfo————");
 
  return null;
 }
 
 /**
  * 認(rèn)證
  */
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  System.out.println("————密碼認(rèn)證————doGetAuthenticationInfo————");
 
  UsernamePasswordToken userToken = (UsernamePasswordToken) token;
  // 連接數(shù)據(jù)庫 查詢用戶數(shù)據(jù)
  QueryWrapper<User> wrapper = new QueryWrapper<>();
  wrapper.eq("user_name", userToken.getUsername());
  User user = userMapper.selectOne(wrapper);
  // 驗(yàn)證用戶
  if (user == null) {
   throw new UnknownAccountException();
  }
  return new SimpleAuthenticationInfo("", user.getUserPassword(), "");
 }
 
 /**
  * 用來判斷是否使用當(dāng)前的 realm
  *
  * @param var1 傳入的token
  * @return true就使用,false就不使用
  */
 @Override
 public boolean supports(AuthenticationToken var1) {
  return var1 instanceof UsernamePasswordToken;
 }
 
}

創(chuàng)建郵件驗(yàn)證碼登錄時(shí)驗(yàn)證授權(quán)UserEmailRealm

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Component
public class UserEmailRealm extends AuthorizingRealm {
 
 // 注入用戶業(yè)務(wù)
 @Autowired
 UserService userService;
 
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
  System.out.println("————郵箱登錄授權(quán)————doGetAuthorizationInfo————");
  return null;
 }
 
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  System.out.println("————郵箱登錄認(rèn)證————doGetAuthenticationInfo————");
  UserEmailToken userEmailToken = (UserEmailToken) token;
  String userEmail = (String) userEmailToken.getPrincipal();
  // 連接數(shù)據(jù)庫 查詢用戶數(shù)據(jù)
  QueryWrapper<User> wrapper = new QueryWrapper<>();
  wrapper.eq("user_email", userEmail);
  User user = userService.getOne(wrapper);
  //因?yàn)闆]有密碼,并且驗(yàn)證碼在之前就驗(yàn)證了
  if (user == null) {
   throw new UnknownAccountException();
  }
  return new SimpleAuthenticationInfo("", userEmail, "");
 }
 
 /**
  * 用來判斷是否使用當(dāng)前的 realm
  *
  * @param var1 傳入的token
  * @return true就使用,false就不使用
  */
 @Override
 public boolean supports(AuthenticationToken var1) {
  return var1 instanceof UserEmailToken;
 }
}

創(chuàng)建郵件驗(yàn)證碼登錄驗(yàn)證通過生成令牌的 UserEmailToken 類(密碼登錄時(shí)使用shiro默認(rèn)的 UsernamePasswordToken 令牌)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@Data // 使用lombok 生成get方法、set方法
public class UserEmailToken implements HostAuthenticationToken, RememberMeAuthenticationToken {
 
 private String userEmail;
 private boolean rememberMe;
 private String host;
 
 public UserEmailToken() {
  this.rememberMe = false;
 }
 
 public UserEmailToken(String userEmail) {
  this(userEmail, false, null);
 }
 
 public UserEmailToken(String userEmail, boolean rememberMe) {
  this(userEmail, rememberMe, null);
 }
 
 public UserEmailToken(String userEmail, boolean rememberMe, String host) {
  this.userEmail = userEmail;
  this.rememberMe = rememberMe;
  this.host = host;
 }
 
 @Override
 public String getHost() {
  return host;
 }
 
 @Override
 public boolean isRememberMe() {
  return rememberMe;
 }
 
 /**
  * 重寫getPrincipal方法
  */
 @Override
 public Object getPrincipal() {
  return userEmail;
 }
 
 /**
  * 重寫getCredentials方法
  */
 @Override
 public Object getCredentials() {
  return userEmail;
 }
}

創(chuàng)建密碼鹽值加密 MDPasswordUtil 工具類

?
1
2
3
4
5
6
7
8
9
10
11
public class MDPasswordUtil {
 
 public String getMDPasswordUtil(String userName, String userPassword) {
  String hashAlgorithmName = "MD5"; // 加密方式:md5加密
  Object credentials = userPassword; // 密碼
  Object salt = ByteSource.Util.bytes(userName); // 鹽
  int hashIterations = 512; // 加密次數(shù)
  Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
  return result.toString();
 }
}

控制層用戶密碼登錄

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 用戶密碼登錄
 @PostMapping("/passwordLogin")
 public String userLogin(@RequestParam("userName") String userName,
       @RequestParam("userPassword") String userPassword,
       HttpSession session, Model model) {
  // 獲取當(dāng)前的用戶
  Subject subject = SecurityUtils.getSubject();
  // 對(duì)密碼進(jìn)行MD5鹽值加密
  String md5Password = new MDPasswordUtil().getMDPasswordUtil(userName, userPassword);
  // 封裝用戶的登錄數(shù)據(jù)
  UsernamePasswordToken token = new UsernamePasswordToken(userName, md5Password);
  //rememberme記住我
  token.setRememberMe(true);
  try {
   // 登錄,驗(yàn)證,保存令牌
   subject.login(token);
 
   //查詢登錄信息
   QueryWrapper<User> wrapper = new QueryWrapper<>();
   wrapper.eq("user_name", userName);
   User user = userService.getOne(wrapper);
   //保存登錄用戶信息
   session.setAttribute(user.getUserId().toString(), user);
 
   return "admin";
  } catch (UnknownAccountException e) {
   model.addAttribute("userError", "用戶名錯(cuò)誤!請(qǐng)重新輸入。");
   return "login";
  } catch (IncorrectCredentialsException ice) {
   model.addAttribute("pwError", "密碼錯(cuò)誤!請(qǐng)重新輸入。");
   return "login";
  }
 }

控制層用戶郵件驗(yàn)證碼密碼登錄

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 用戶郵箱登錄
 @PostMapping("/emailLogin")
 public String emailLogin(@RequestParam("userEmail") String userEmail,
        @RequestParam("emailCode") String emailCode,
        HttpSession session, Model model) {
  // 根據(jù)userEmail從session中取出發(fā)送的驗(yàn)證碼
  String sendEmailCode = (String) session.getAttribute(userEmail);
  // 比對(duì)驗(yàn)證碼
  if (StringUtils.isNoneBlank(sendEmailCode) && sendEmailCode.equals(emailCode)) {
   try {
    UserEmailToken token = new UserEmailToken(userEmail);
    //rememberme記住我
    token.setRememberMe(true);
    // 登錄,驗(yàn)證,保存令牌
    Subject subject = SecurityUtils.getSubject();
    subject.login(token);
 
    //查詢登錄信息
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("user_email", userEmail);
    User user = userService.getOne(wrapper);
    //保存登錄用戶信息
    session.setAttribute(user.getUserId().toString(), user);
 
    // 銷毀驗(yàn)證碼
    session.removeAttribute(emailCode);
 
    return "admin";
   } catch (Exception e) {
    model.addAttribute("error", "驗(yàn)證碼錯(cuò)誤!請(qǐng)重新輸入。");
    return "login";
   }
  } else {
   return "login";
  }
 }

SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄(多 Realm 認(rèn)證)就可以了 (有點(diǎn)多,哈哈哈)

推薦大神:狂神說Java

到此這篇關(guān)于SpringBoot 整合 Shiro 密碼登錄與郵件驗(yàn)證碼登錄(多 Realm 認(rèn)證)的文章就介紹到這了,更多相關(guān)SpringBoot 整合 Shiro登錄內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:http://www.cnblogs.com/dmflysky/p/14449727.html

延伸 · 閱讀

精彩推薦
  • Java教程Docker使用 Maven 插件構(gòu)建鏡像的方法

    Docker使用 Maven 插件構(gòu)建鏡像的方法

    本篇文章主要介紹了Docker使用 Maven 插件構(gòu)建鏡像的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧...

    林塬10592021-04-04
  • Java教程Java利用Redis實(shí)現(xiàn)高并發(fā)計(jì)數(shù)器的示例代碼

    Java利用Redis實(shí)現(xiàn)高并發(fā)計(jì)數(shù)器的示例代碼

    這篇文章主要介紹了Java利用Redis實(shí)現(xiàn)高并發(fā)計(jì)數(shù)器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要...

    李秀才10312021-08-12
  • Java教程Java爬蟲技術(shù)框架之Heritrix框架詳解

    Java爬蟲技術(shù)框架之Heritrix框架詳解

    這篇文章主要介紹了爬蟲技術(shù)框架之Heritrix框架詳解,文中通過示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面...

    moonsoft2272020-07-23
  • Java教程JavaWeb文件下載功能實(shí)例代碼

    JavaWeb文件下載功能實(shí)例代碼

    這篇文章主要為大家詳細(xì)介紹了JavaWeb文件下載功能實(shí)例代碼,代碼簡單實(shí)用,感興趣的小伙伴們可以參考一下 ...

    sennhai4532020-05-22
  • Java教程Java面向?qū)ο筮x擇題總結(jié)歸納

    Java面向?qū)ο筮x擇題總結(jié)歸納

    今天小編就為大家分享一篇關(guān)于Java面向?qū)ο筮x擇題總結(jié)歸納,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來...

    kuls6402021-07-02
  • Java教程JAVA幫助文檔全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版整理

    JAVA幫助文檔全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版整理

    JDK(Java Development Kit,Java開發(fā)包,Java開發(fā)工具)是一個(gè)寫Java的applet和應(yīng)用程序的程序開發(fā)環(huán)境。它由一個(gè)處于操作系統(tǒng)層之上的運(yùn)行環(huán)境還有開發(fā)者編譯,調(diào)...

    java教程網(wǎng)2672019-10-31
  • Java教程UrlRewrite 重寫url詳解及實(shí)例

    UrlRewrite 重寫url詳解及實(shí)例

    這篇文章主要介紹了UrlRewrite 重寫url詳解及實(shí)例的相關(guān)資料,重寫能美化,提高安全,有利于搜索引擎的收入等,需要的朋友可以參考下 ...

    劉彥亮2382020-07-10
  • Java教程IDEA項(xiàng)目重命名的操作

    IDEA項(xiàng)目重命名的操作

    這篇文章主要介紹了IDEA項(xiàng)目重命名的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧...

    fastjson_7222021-08-06
主站蜘蛛池模板: 国产精品一区二区三区不卡 | 亚洲成av人片一区二区梦乃 | 国产精品一区二区三区四区 | 精品影院 | 日本中文在线 | 成人3d动漫一区二区三区91 | 亚洲欧美日韩精品久久亚洲区 | 久久99深爱久久99精品 | 在线观看欧美日韩 | 96久久久| 欧美午夜一区二区福利视频 | 色爱区综合五月激情 | 国产成人一区 | 国产一级片免费观看 | 91视频 - 88av | 日本免费在线一区 | 成人av网站在线观看 | 美女久久久| 国产高清免费 | 久久99这里只有精品 | 国产中文视频 | 国内成人综合 | 精品免费久久久久久久苍 | 看一级黄色大片 | 狠狠综合 | 欧美伊人| 日韩视频免费在线播放 | 成人国产精品 | 在线观看国产视频 | 色九九九 | 婷婷色综合 | 国产午夜精品一区二区三区免费 | 久久久网页 | 求av网址 | 亚洲成人日韩在线 | 亚洲日本韩国在线观看 | 午夜精品一区二区三区免费视频 | 午夜免费av | 免费观看一级毛片 | 永久黄网站色视频免费观看w | 午夜精品视频在线观看 |