最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringSecurity?Web權(quán)限方案實(shí)現(xiàn)全過(guò)程

 更新時(shí)間:2024年01月31日 09:48:33   作者:zoeil  
Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和授權(quán)框架,專(zhuān)門(mén)用于保護(hù)Java應(yīng)用程序的Web集成,下面這篇文章主要給大家介紹了關(guān)于SpringSecurity?Web權(quán)限方案實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下

一、設(shè)置登錄系統(tǒng)的賬號(hào)、密碼

方式一,配置文件application.properties

spring.security.user.name=lucy
spring.security.user.password=123

方式二,編寫(xiě)配置類(lèi)

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode("123");
        auth.inMemoryAuthentication().withUser("zhangsan").password(password).roles("admin");
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

方式三,通過(guò)類(lèi)實(shí)現(xiàn)接口UserDetailService

@Service
public class userDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException 
        List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        return new User("zhangsan", new BCryptPasswordEncoder().encode("123"), list);
    }
}

二、數(shù)據(jù)庫(kù)查詢用戶名密碼

引入依賴

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

建表sql

create table users(
    id bigint primary key auto_increment,
    username varchar(20) unique not null,
    password varchar(100)
);

數(shù)據(jù)源配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?serverTimezone= GMT%2B8
    username: root
    password: 123456

實(shí)體類(lèi)users

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Users {
    private Integer id;
    private String username;
    private String password;
}

mapper

@Mapper
public interface UserMapper extends BaseMapper<Users> {
}

修改userDetailService

@Service
public class userDetailsService implements UserDetailsService {

    @Autowired
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        // 使用mapper查詢數(shù)據(jù)庫(kù)
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", s);
        Users users = userMapper.selectOne(queryWrapper);
        if (users == null) {
            throw new UsernameNotFoundException("用戶名不存在!");
        }

        List<GrantedAuthority> list = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        return new User(users.getUsername(), new BCryptPasswordEncoder().encode(users.getPassword()), list);

    }
}

修改SecurityConfigTest 

@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

三、自定義登錄頁(yè)面

在配置類(lèi)SpringSecurity中重寫(xiě)configure方法

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() //自定義自己編寫(xiě)的登錄頁(yè)面
                .loginPage("/login.html") //登錄頁(yè)面設(shè)置
                .loginProcessingUrl("/user/login") //登錄訪問(wèn)路徑
                .defaultSuccessUrl("/test/index").permitAll() //登錄成功之后,跳轉(zhuǎn)路徑
                .and().authorizeRequests()
                .antMatchers("/", "/test/hello","/user/login").permitAll() // 設(shè)置哪些路徑可以直接訪問(wèn),不需要認(rèn)證
                .anyRequest().authenticated()
                .and().csrf().disable(); // 關(guān)閉csrf防護(hù)
    }

再編寫(xiě)登錄頁(yè)面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/user/login" method="post">
        用戶名:<input type="text" name="username"/>
        <br/>
        密碼:<input type="password" name="password"/><br/>
        <input type="submit" value="login"/>
    </form>
</body>
</html>

controlller

@RestController
@RequestMapping("/test")
public class HelloController {

    @GetMapping("/hello")
    public String test() {
        return "hello, security";
    }
    @GetMapping("/index")
    public String index() {
        return "hello, index";
    }
}

啟動(dòng)項(xiàng)目后使用的登錄頁(yè)面就是我們編寫(xiě)的 了

四、基于角色或權(quán)限進(jìn)行訪問(wèn)控制

(一)hasAuthority 方法

如果當(dāng)前的主體具有指定的權(quán)限,則返回 true,否則返回 false

設(shè)置訪問(wèn)/test/index需要admin角色

給用戶添加admin角色 

 修改角色為別的,不是admin后訪問(wèn)被禁止

(二)hasAnyAuthority 方法

如果當(dāng)前的主體有任何提供的角色(給定的作為一個(gè)逗號(hào)分隔的字符串列表)的話,返回 true.

(三)hasRole 方法

如果用戶具備給定角色就允許訪問(wèn) , 否則出現(xiàn) 403 。

如果當(dāng)前主體具有指定的角色,則返回 true 。

底層源碼:

 給用戶添加角色需要加上前綴ROLE_

修改配置文件:

注意配置文件中不需要添加” ROLE_ “,因?yàn)樯鲜龅牡讓哟a會(huì)自動(dòng)添加與之進(jìn)行匹配。

(四)hasAnyRole

表示用戶具備任何一個(gè)條件都可以訪問(wèn)。

給用戶添加角色:

修改配置文件:

五、自定義403頁(yè)面 

在配置類(lèi)中配置

編寫(xiě)unauth頁(yè)面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>沒(méi)有訪問(wèn)權(quán)限</h1>
</body>
</html>

 跳轉(zhuǎn)成功

六、注解使用

(一)@Secured

判斷是否具有角色,另外需要注意的是這里匹配的字符串需要添加前綴“ ROLE_ “。

使用注解先要開(kāi)啟注解功能!

@EnableGlobalMethodSecurity(securedEnabled=true)

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled=true)
    public class DemosecurityApplication {
    public static void main(String[] args) {
         SpringApplication.run(DemosecurityApplication.class, args);
    }
}

 controller

    @GetMapping("/update")
    @Secured({"ROLE_admin"})
    public String update() {
        return "hello, update";
    }

(二)@PreAuthorize

先開(kāi)啟注解功能:

@EnableGlobalMethodSecurity (prePostEnabled = true )

@PreAuthorize:注解適合進(jìn)入方法前的權(quán)限驗(yàn)證, @PreAuthorize 可以將登錄用戶的 roles/permissions 參數(shù)傳到方法中。

    @GetMapping("/update")
    @PreAuthorize("hasAnyAuthority('admin')")
    public String update() {
        return "hello, update";
    }

(三)@PostAuthorize

先開(kāi)啟注解功能:

@EnableGlobalMethodSecurity (prePostEnabled = true )

@PostAuthorize 注解使用并不多,在方法執(zhí)行后再進(jìn)行權(quán)限驗(yàn)證,適合驗(yàn)證帶有返回值的權(quán)限.

@RequestMapping("/testPostAuthorize")
@ResponseBody
@PostAuthorize("hasAnyAuthority('admin')")
public String preAuthorize(){
     System.out.println("test--PostAuthorize");
     return "PostAuthorize";
}

(四)@PreFilter

@PreFilter: 進(jìn)入控制器之前對(duì)數(shù)據(jù)進(jìn)行過(guò)濾

@RequestMapping("getTestPreFilter")
@PreAuthorize("hasRole('ROLE_管理員')")
@PreFilter(value = "filterObject.id%2==0")
@ResponseBody
public List<UserInfo> getTestPreFilter(@RequestBody List<UserInfo> list){
    list.forEach(t-> {
        System.out.println(t.getId()+"\t"+t.getUsername());
    });
    return list;
}

(五)@PostFilter

@PostFilter :權(quán)限驗(yàn)證之后對(duì)數(shù)據(jù)進(jìn)行過(guò)濾 留下用戶名是 admin1 的數(shù)據(jù)

表達(dá)式中的 filterObject 引用的是方法返回值 List 中的某一個(gè)元素

@RequestMapping("getAll")
@PreAuthorize("hasRole('ROLE_管理員')")
@PostFilter("filterObject.username == 'admin1'")
@ResponseBody
public List<UserInfo> getAllUser(){
    ArrayList<UserInfo> list = new ArrayList<>();
    list.add(new UserInfo(1l,"admin1","6666"));
    list.add(new UserInfo(2l,"admin2","888"));
    return list;
}

七、基于數(shù)據(jù)庫(kù)的記住我

使用spring security記住登錄的用戶原理

創(chuàng)建表

CREATE TABLE `persistent_logins` (
 `username` varchar(64) NOT NULL,
 `series` varchar(64) NOT NULL,
 `token` varchar(64) NOT NULL,
 `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE 
CURRENT_TIMESTAMP,
 PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

配置文件編寫(xiě)數(shù)據(jù)庫(kù)的配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?serverTimezone= GMT%2B8
    username: root
    password: 123456

配置類(lèi)

默認(rèn) 2 周時(shí)間。但是可以通過(guò)設(shè)置狀態(tài)有效時(shí)間,即使項(xiàng)目重新啟動(dòng)下次也可以正常登錄。

頁(yè)面添加記住我復(fù)選框,此處: name 屬性值必須為  remember-me. 不能改為其他值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <form action="/user/login" method="post">
        用戶名:<input type="text" name="username"/>
        <br/>
        密碼:<input type="password" name="password"/><br/>
        <input type="checkbox" name="remember-me"/>60s內(nèi)免登錄<br/>
        <input type="submit" value="login"/>
    </form>
</body>
</html>

八、CSRF

跨站請(qǐng)求偽造 (英語(yǔ): Cross-site request forgery ),也被稱為 one-click attack 或者 session riding ,通??s寫(xiě)為 CSRF 或者 XSRF , 是一種挾制用戶在當(dāng)前已登錄的 Web 應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。跟 跨網(wǎng)站腳本 ( XSS )相比, XSS 利用的是用戶對(duì)指定網(wǎng)站的信任,CSRF 利用的是網(wǎng)站對(duì)用戶網(wǎng)頁(yè)瀏覽器的信任。

跨站請(qǐng)求攻擊,簡(jiǎn)單地說(shuō),是攻擊者通過(guò)一些技術(shù)手段欺騙用戶的瀏覽器去訪問(wèn)一個(gè)自己曾經(jīng)認(rèn)證過(guò)的網(wǎng)站并運(yùn)行一些操作(如發(fā)郵件,發(fā)消息,甚至財(cái)產(chǎn)操作如轉(zhuǎn)賬和購(gòu)買(mǎi)商品)。由于瀏覽器曾經(jīng)認(rèn)證過(guò),所以被訪問(wèn)的網(wǎng)站會(huì)認(rèn)為是真正的用戶操作而去運(yùn)行。

這利用了 web 中用戶身份驗(yàn)證的一個(gè)漏洞: 簡(jiǎn)單的身份驗(yàn)證只能保證請(qǐng)求發(fā)自某個(gè)用戶的瀏覽 器,卻不能保證請(qǐng)求本身是用戶自愿發(fā)出的 。

從 Spring Security 4.0 開(kāi)始,默認(rèn)情況下會(huì)啟用 CSRF 保護(hù),以防止 CSRF 攻擊應(yīng)用程序,Spring Security CSRF 會(huì)針對(duì) PATCH , POST , PUT 和 DELETE 方法進(jìn)行防護(hù)。

總結(jié)

到此這篇關(guān)于SpringSecurity Web權(quán)限方案實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringSecurity Web權(quán)限內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java泛型extends關(guān)鍵字設(shè)置邊界的實(shí)現(xiàn)

    Java泛型extends關(guān)鍵字設(shè)置邊界的實(shí)現(xiàn)

    這篇文章主要介紹了Java泛型extends關(guān)鍵字設(shè)置邊界的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java 序列化詳解及簡(jiǎn)單實(shí)現(xiàn)實(shí)例

    Java 序列化詳解及簡(jiǎn)單實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了 Java 序列化詳解及簡(jiǎn)單實(shí)現(xiàn)實(shí)例的相關(guān)資料,使用序列化目的:以某種存儲(chǔ)形式使自定義對(duì)象持久化,將對(duì)象從一個(gè)地方傳遞到另一個(gè)地方,需要的朋友可以參考下
    2017-03-03
  • Springboot?Filter中注入bean無(wú)效為null問(wèn)題

    Springboot?Filter中注入bean無(wú)效為null問(wèn)題

    這篇文章主要介紹了Springboot?Filter中注入bean無(wú)效為null問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 淺談mybatis如何半自動(dòng)化解耦(推薦)

    淺談mybatis如何半自動(dòng)化解耦(推薦)

    這篇文章主要介紹了淺談mybatis如何半自動(dòng)化解耦,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java判斷多個(gè)時(shí)間段是否重合的方法小結(jié)

    Java判斷多個(gè)時(shí)間段是否重合的方法小結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java中判斷多個(gè)時(shí)間段是否重合的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • 淺談PrintStream和PrintWriter的區(qū)別和聯(lián)系

    淺談PrintStream和PrintWriter的區(qū)別和聯(lián)系

    這篇文章主要介紹了淺談PrintStream和PrintWriter的區(qū)別和聯(lián)系,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 使用maven基本命令,打包包名問(wèn)題

    使用maven基本命令,打包包名問(wèn)題

    這篇文章主要介紹了使用maven基本命令,打包包名問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • SpringBoot中Bean生命周期自定義初始化和銷(xiāo)毀方法詳解

    SpringBoot中Bean生命周期自定義初始化和銷(xiāo)毀方法詳解

    這篇文章給大家詳細(xì)介紹了SpringBoot中Bean生命周期自定義初始化和銷(xiāo)毀方法,文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • 詳解Java如何實(shí)現(xiàn)多線程步調(diào)一致

    詳解Java如何實(shí)現(xiàn)多線程步調(diào)一致

    本章節(jié)主要講解另外兩個(gè)線程同步器:CountDownLatch和CyclicBarrier的用法,使用場(chǎng)景以及實(shí)現(xiàn)原理,感興趣的小伙伴可以了解一下
    2023-07-07
  • Java 中 Date 與 Calendar 之間的編輯與轉(zhuǎn)換實(shí)例詳解

    Java 中 Date 與 Calendar 之間的編輯與轉(zhuǎn)換實(shí)例詳解

    這篇文章主要介紹了Java 中 Date 與 Calendar 之間的編輯與轉(zhuǎn)換 ,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07

最新評(píng)論

抚顺县| 扎兰屯市| 日喀则市| 新安县| 康定县| 莱州市| 延吉市| 攀枝花市| 苏尼特左旗| 介休市| 高密市| 牙克石市| 北海市| 泾川县| 马公市| 中卫市| 金山区| 都江堰市| 汤阴县| 岳普湖县| 沙田区| 香港 | 离岛区| 景洪市| 临朐县| 宁强县| 同德县| 长白| 赤峰市| 平南县| 股票| 黑水县| 柞水县| 桂阳县| 渝中区| 呼伦贝尔市| 沙湾县| 罗源县| 阜南县| 虎林市| 剑河县|