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

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - SpringSecurity登錄使用JSON格式數據的方法

SpringSecurity登錄使用JSON格式數據的方法

2021-07-15 14:48江南一點雨 Java教程

這篇文章主要介紹了SpringSecurity登錄使用JSON格式數據的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在使用springsecurity中,大伙都知道默認的登錄數據是通過key/value的形式來傳遞的,默認情況下不支持json格式的登錄數據,如果有這種需求,就需要自己來解決,本文主要和小伙伴來聊聊這個話題。

基本登錄方案

在說如何使用json登錄之前,我們還是先來看看基本的登錄吧,本文為了簡單,springsecurity在使用中就不連接數據庫了,直接在內存中配置用戶名和密碼,具體操作步驟如下:

創建spring boot工程

首先創建springboot工程,添加springsecurity依賴,如下:

?
1
2
3
4
5
6
7
8
<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-security</artifactid>
</dependency>
<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-web</artifactid>
</dependency>

添加security配置

創建securityconfig,完成springsecurity的配置,如下:

?
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
@configuration
public class securityconfig extends websecurityconfigureradapter {
  @bean
  passwordencoder passwordencoder() {
    return new bcryptpasswordencoder();
  }
  @override
  protected void configure(authenticationmanagerbuilder auth) throws exception {
    auth.inmemoryauthentication().withuser("zhangsan").password("$2a$10$2o4ewlrrfpebotfdotc0f.rpumk.3q3kvbhrx7xxkumlbgjoobs8q").roles("user");
  }
 
  @override
  public void configure(websecurity web) throws exception {
  }
 
  @override
  protected void configure(httpsecurity http) throws exception {
    http.authorizerequests()
        .anyrequest().authenticated()
        .and()
        .formlogin()
        .loginprocessingurl("/dologin")
        .successhandler(new authenticationsuccesshandler() {
          @override
          public void onauthenticationsuccess(httpservletrequest req, httpservletresponse resp, authentication authentication) throws ioexception, servletexception {
            respbean ok = respbean.ok("登錄成功!",authentication.getprincipal());
            resp.setcontenttype("application/json;charset=utf-8");
            printwriter out = resp.getwriter();
            out.write(new objectmapper().writevalueasstring(ok));
            out.flush();
            out.close();
          }
        })
        .failurehandler(new authenticationfailurehandler() {
          @override
          public void onauthenticationfailure(httpservletrequest req, httpservletresponse resp, authenticationexception e) throws ioexception, servletexception {
            respbean error = respbean.error("登錄失敗");
            resp.setcontenttype("application/json;charset=utf-8");
            printwriter out = resp.getwriter();
            out.write(new objectmapper().writevalueasstring(error));
            out.flush();
            out.close();
          }
        })
        .loginpage("/login")
        .permitall()
        .and()
        .logout()
        .logouturl("/logout")
        .logoutsuccesshandler(new logoutsuccesshandler() {
          @override
          public void onlogoutsuccess(httpservletrequest req, httpservletresponse resp, authentication authentication) throws ioexception, servletexception {
            respbean ok = respbean.ok("注銷成功!");
            resp.setcontenttype("application/json;charset=utf-8");
            printwriter out = resp.getwriter();
            out.write(new objectmapper().writevalueasstring(ok));
            out.flush();
            out.close();
          }
        })
        .permitall()
        .and()
        .csrf()
        .disable()
        .exceptionhandling()
        .accessdeniedhandler(new accessdeniedhandler() {
          @override
          public void handle(httpservletrequest req, httpservletresponse resp, accessdeniedexception e) throws ioexception, servletexception {
            respbean error = respbean.error("權限不足,訪問失敗");
            resp.setstatus(403);
            resp.setcontenttype("application/json;charset=utf-8");
            printwriter out = resp.getwriter();
            out.write(new objectmapper().writevalueasstring(error));
            out.flush();
            out.close();
          }
        });
 
  }
}

這里的配置雖然有點長,但是很基礎,配置含義也比較清晰,首先提供bcryptpasswordencoder作為passwordencoder,可以實現對密碼的自動加密加鹽,非常方便,然后提供了一個名為zhangsan的用戶,密碼是123,角色是user,最后配置登錄邏輯,所有的請求都需要登錄后才能訪問,登錄接口是/dologin,用戶名的key是username,密碼的key是password,同時配置登錄成功、登錄失敗以及注銷成功、權限不足時都給用戶返回json提示,另外,這里雖然配置了登錄頁面為/login,實際上這不是一個頁面,而是一段json,在logincontroller中提供該接口,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
@restcontroller
@responsebody
public class logincontroller {
  @getmapping("/login")
  public respbean login() {
    return respbean.error("尚未登錄,請登錄");
  }
  @getmapping("/hello")
  public string hello() {
    return "hello";
  }
}

這里/login只是一個json提示,而不是頁面, /hello則是一個測試接口。

ok,做完上述步驟就可以開始測試了,運行springboot項目,訪問/hello接口,結果如下:

SpringSecurity登錄使用JSON格式數據的方法

此時先調用登錄接口進行登錄,如下:

SpringSecurity登錄使用JSON格式數據的方法

登錄成功后,再去訪問/hello接口就可以成功訪問了。

使用json登錄

上面演示的是一種原始的登錄方案,如果想將用戶名密碼通過json的方式進行傳遞,則需要自定義相關過濾器,通過分析源碼我們發現,默認的用戶名密碼提取在usernamepasswordauthenticationfilter過濾器中,部分源碼如下:

?
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
public class usernamepasswordauthenticationfilter extends
    abstractauthenticationprocessingfilter {
  public static final string spring_security_form_username_key = "username";
  public static final string spring_security_form_password_key = "password";
 
  private string usernameparameter = spring_security_form_username_key;
  private string passwordparameter = spring_security_form_password_key;
  private boolean postonly = true;
  public usernamepasswordauthenticationfilter() {
    super(new antpathrequestmatcher("/login", "post"));
  }
 
  public authentication attemptauthentication(httpservletrequest request,
      httpservletresponse response) throws authenticationexception {
    if (postonly && !request.getmethod().equals("post")) {
      throw new authenticationserviceexception(
          "authentication method not supported: " + request.getmethod());
    }
 
    string username = obtainusername(request);
    string password = obtainpassword(request);
 
    if (username == null) {
      username = "";
    }
 
    if (password == null) {
      password = "";
    }
 
    username = username.trim();
 
    usernamepasswordauthenticationtoken authrequest = new usernamepasswordauthenticationtoken(
        username, password);
 
    // allow subclasses to set the "details" property
    setdetails(request, authrequest);
 
    return this.getauthenticationmanager().authenticate(authrequest);
  }
 
  protected string obtainpassword(httpservletrequest request) {
    return request.getparameter(passwordparameter);
  }
 
  protected string obtainusername(httpservletrequest request) {
    return request.getparameter(usernameparameter);
  }
  //...
  //...
}

從這里可以看到,默認的用戶名/密碼提取就是通過request中的getparameter來提取的,如果想使用json傳遞用戶名密碼,只需要將這個過濾器替換掉即可,自定義過濾器如下:

?
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 customauthenticationfilter extends usernamepasswordauthenticationfilter {
  @override
  public authentication attemptauthentication(httpservletrequest request, httpservletresponse response) throws authenticationexception {
    if (request.getcontenttype().equals(mediatype.application_json_utf8_value)
        || request.getcontenttype().equals(mediatype.application_json_value)) {
      objectmapper mapper = new objectmapper();
      usernamepasswordauthenticationtoken authrequest = null;
      try (inputstream is = request.getinputstream()) {
        map<string,string> authenticationbean = mapper.readvalue(is, map.class);
        authrequest = new usernamepasswordauthenticationtoken(
            authenticationbean.get("username"), authenticationbean.get("password"));
      } catch (ioexception e) {
        e.printstacktrace();
        authrequest = new usernamepasswordauthenticationtoken(
            "", "");
      } finally {
        setdetails(request, authrequest);
        return this.getauthenticationmanager().authenticate(authrequest);
      }
    }
    else {
      return super.attemptauthentication(request, response);
    }
  }
}

這里只是將用戶名/密碼的獲取方案重新修正下,改為了從json中獲取用戶名密碼,然后在securityconfig中作出如下修改:

?
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
@override
protected void configure(httpsecurity http) throws exception {
  http.authorizerequests().anyrequest().authenticated()
      .and()
      .formlogin()
      .and().csrf().disable();
  http.addfilterat(customauthenticationfilter(), usernamepasswordauthenticationfilter.class);
}
@bean
customauthenticationfilter customauthenticationfilter() throws exception {
  customauthenticationfilter filter = new customauthenticationfilter();
  filter.setauthenticationsuccesshandler(new authenticationsuccesshandler() {
    @override
    public void onauthenticationsuccess(httpservletrequest req, httpservletresponse resp, authentication authentication) throws ioexception, servletexception {
      resp.setcontenttype("application/json;charset=utf-8");
      printwriter out = resp.getwriter();
      respbean respbean = respbean.ok("登錄成功!");
      out.write(new objectmapper().writevalueasstring(respbean));
      out.flush();
      out.close();
    }
  });
  filter.setauthenticationfailurehandler(new authenticationfailurehandler() {
    @override
    public void onauthenticationfailure(httpservletrequest req, httpservletresponse resp, authenticationexception e) throws ioexception, servletexception {
      resp.setcontenttype("application/json;charset=utf-8");
      printwriter out = resp.getwriter();
      respbean respbean = respbean.error("登錄失敗!");
      out.write(new objectmapper().writevalueasstring(respbean));
      out.flush();
      out.close();
    }
  });
  filter.setauthenticationmanager(authenticationmanagerbean());
  return filter;
}

將自定義的customauthenticationfilter類加入進來即可,接下來就可以使用json進行登錄了,如下:

SpringSecurity登錄使用JSON格式數據的方法

好了,本文就先介紹到這里,有問題歡迎留言討論。 希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000018157525

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: av成人免费 | 成人精品在线观看 | 毛片网站在线 | 一级在线观看 | 国产精品久久久亚洲 | 亚洲国内精品 | 成人高清视频在线观看 | 久久人人爽爽爽人久久久 | 性欧美精品久久久久久久 | 国产一级毛片一级 | 亚洲精品久久久久久久久久久 | 国产一区二区三区 | 毛片黄片 | 毛片免费观看网址 | 欧美喷水 | 亚洲国产精品一区二区久久,亚洲午夜 | 国产一区二区三区视频 | 成人动慢 | 国产欧美日韩一区二区三区 | 成人伊人网| 欧美国产激情二区三区 | 中文字幕免费在线 | 毛片一级片 | 一区二区三区亚洲 | 亚洲高清在线视频 | av网站免费看 | 操av在线 | 青青草原综合久久大伊人精品 | 成人午夜视频在线观看 | 91尤物网站网红尤物福利 | 午夜精品在线 | 久久黄视频| 精品久 | 日韩在线一区二区 | 久久噜噜噜精品国产亚洲综合 | 精品国产区 | 免费看片www| 特黄视频免费观看 | 亚洲二区在线播放 | 日韩免费观看视频 | 亚洲精品久久久久久国产精华液 |