当前位置: 代码网 > it编程>编程语言>Java > SpringSecurity自定义登录接口的实现

SpringSecurity自定义登录接口的实现

2025年01月21日 Java 我要评论
1.pom依赖 <dependencies> <dependency> <groupid>org.springframework

1.pom依赖

 <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-security</artifactid>
            <version>2.7.10</version>
        </dependency>

        <dependency>
            <groupid>com.alibaba</groupid>
            <artifactid>fastjson</artifactid>
            <version>1.2.83</version>
        </dependency>

        <!--<dependency>-->
            <!--<groupid>org.springframework.session</groupid>-->
            <!--<artifactid>spring-session-data-redis</artifactid>-->
        <!--</dependency>-->

        <!--<dependency>-->
            <!--<groupid>redis.clients</groupid>-->
            <!--<artifactid>jedis</artifactid>-->
            <!--<version>3.6.3</version>-->
        <!--</dependency>-->


        <!--<dependency>-->
            <!--<groupid>org.springframework.boot</groupid>-->
            <!--<artifactid>spring-boot-starter-data-redis</artifactid>-->
            <!--<exclusions>-->
                <!--<exclusion>-->
                    <!--<groupid>io.lettuce</groupid>-->
                    <!--<artifactid>lettuce-core</artifactid>-->
                <!--</exclusion>-->
            <!--</exclusions>-->
        <!--</dependency>-->
    </dependencies>

2.配置类

package com.example.springsecuritytest.config;

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.security.authentication.authenticationmanager;
import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder;
import org.springframework.security.config.annotation.method.configuration.enableglobalmethodsecurity;
import org.springframework.security.config.annotation.web.builders.httpsecurity;
import org.springframework.security.config.annotation.web.configuration.enablewebsecurity;
import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
import org.springframework.security.crypto.password.passwordencoder;

@configuration
@enablewebsecurity//开启spring security的功能
@enableglobalmethodsecurity(prepostenabled=true)
public class websecurityconfig extends websecurityconfigureradapter {



    //链式编程
    @override
    protected void configure(httpsecurity http) throws exception{
        //请求授权的规则
        http.authorizerequests()
                //未登录可以直接访问
                .antmatchers("/loginuser/**").permitall()
                //admin权限可以访问(此处可以指定不同的权限访问不同的路径)
                .antmatchers("/**").hasanyauthority("admin")
                .anyrequest().authenticated();// 其他都需要登录认证;

        //注销,开启了注销功能,跳到首页
        //http.logout().logoutsuccessurl("/");
        //定制登录页(没有登录默认跳转的路径)
        http.formlogin().loginpage("/loginuser/nologin");

        http.logout().logouturl("/signout").logoutsuccessurl("/loginuser/signoutsuccess");


        http.exceptionhandling().accessdeniedpage("/loginuser/fail");
        // 允许跨域请求
        http.csrf(csrf -> csrf.disable());
    }

    @override
    protected void configure(authenticationmanagerbuilder auth) throws exception {
        super.configure(auth);

    }


    /**
     * 指定加密方式
     */
    @bean
    public passwordencoder passwordencoder(){
        // 使用bcrypt加密密码
        return new bcryptpasswordencoder();
    }

    @bean
    @override
    public authenticationmanager authenticationmanagerbean() throws exception {
        return super.authenticationmanagerbean();
    }
}

3.controller层

3.1用户controller

package com.example.springsecuritytest.controller;

import com.example.springsecuritytest.service.userservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
@requestmapping("/loginuser")
public class logincontroller {

    @autowired
    private userservice userservice;

    @requestmapping("/login")
    public string login(string username,string pwd){
        return userservice.login(username,pwd);
    }

    @requestmapping("/nologin")
    public string nologin(){
        return "没有登录认证";
    }

    @requestmapping("/signoutsuccess")
    public string signout(){
        return "登出成功";
    }

    @requestmapping("/fail")
    public string fail(){
        return "您无权进行此操作";
    }
}

3.2测试controller

package com.example.springsecuritytest.controller;

import org.springframework.web.bind.annotation.postmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
/**
 * 下两个方法需要登录认证后,才能访问
 */
@restcontroller
public class testcontroller {

    @requestmapping("/test")
    public string test(){
        return "success";
    }

    @postmapping("/select")
    public string select(){
        return "查询成功";
    }
}

4.entity层

4.1用户类

package com.example.springsecuritytest.entity;

public class user {

    private string username;
    private string pwd;

    public string getusername() {
        return username;
    }

    public void setusername(string username) {
        this.username = username;
    }

    public string getpwd() {
        return pwd;
    }

    public void setpwd(string pwd) {
        this.pwd = pwd;
    }
}

4.2 用户认证信息类

package com.example.springsecuritytest.entity;

import org.springframework.security.core.grantedauthority;
import org.springframework.security.core.userdetails.userdetails;

import java.util.collection;
import java.util.list;

/**
 * userdetails是一个核心接口,它代表了一个认证用户的详细信息。
 * userdetails接口定义了一些基本的方法,用于获取用户的基本信息和授权信息。
 * 当一个用户进行身份验证时(比如通过用户名和密码登录),spring security会创建一个userdetails的实例,
 * 这个实例会包含用户的认证信息,并可以用于后续的授权决策。userdetails接口的主要方法包括:
 *
 * getusername(): 返回用户的用户名。
 * getpassword(): 返回用户的密码。注意,密码通常会被加密或哈希处理。
 * getauthorities(): 返回一个collection,其中包含grantedauthority对象,这些对象表示用户被授予的权限。
 * isaccountnonexpired(): 返回一个布尔值,指示用户的账户是否未过期。
 * isaccountnonlocked(): 返回一个布尔值,指示用户的账户是否被锁定。
 * iscredentialsnonexpired(): 返回一个布尔值,指示用户的凭证(如密码)是否未过期。
 * isenabled(): 返回一个布尔值,指示用户账户是否启用。
 */
public class userdetail implements userdetails {

    private list<grantedauthority> authorities;

    private user user;

    @override
    public collection<? extends grantedauthority> getauthorities() {
        return this.authorities;
    }

    @override
    public string getpassword() {
        return user.getpwd();
    }

    @override
    public string getusername() {
        return user.getusername();
    }

    @override
    public boolean isaccountnonexpired() {
        return true;
    }

    @override
    public boolean isaccountnonlocked() {
        return true;
    }

    @override
    public boolean iscredentialsnonexpired() {
        return true;
    }

    @override
    public boolean isenabled() {
        return true;
    }

    public void setauthorities(list<grantedauthority> authorities) {
        this.authorities = authorities;
    }

    public user getuser() {
        return user;
    }

    public void setuser(user user) {
        this.user = user;
    }
}

5.service层

5.1用户登录service

package com.example.springsecuritytest.service;

public interface userservice {
    public string login(string username,string pwd);
}

5.2用户登录service实现

package com.example.springsecuritytest.service;

import com.alibaba.fastjson.json;
import com.example.springsecuritytest.entity.userdetail;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.security.authentication.authenticationmanager;
import org.springframework.security.authentication.usernamepasswordauthenticationtoken;
import org.springframework.security.core.authentication;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.stereotype.service;

import java.util.objects;

@service
public class userserviceimpl implements userservice {

    @autowired
    private authenticationmanager authenticationmanager;


    @override
    public string login(string username, string pwd) {
        // 用户认证
        //进行用户认证
        usernamepasswordauthenticationtoken authenticationtoken = new usernamepasswordauthenticationtoken(username,pwd);
        authentication authenticate = authenticationmanager.authenticate(authenticationtoken);
        //认证未通过,给出提示
        if(objects.isnull(authenticate)){
            throw new runtimeexception("登陆失败!");

        }

        // 认证成功将用户信息设置进security上下文
        securitycontextholder.getcontext().setauthentication(authenticate);

        userdetail userdetail = (userdetail)authenticate.getprincipal();
        return json.tojsonstring(userdetail.getuser());
    }
}

5.3 用户认证service

package com.example.springsecuritytest.service;

import com.example.springsecuritytest.entity.user;
import com.example.springsecuritytest.entity.userdetail;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.security.core.grantedauthority;
import org.springframework.security.core.userdetails.userdetails;
import org.springframework.security.core.userdetails.userdetailsservice;
import org.springframework.security.core.userdetails.usernamenotfoundexception;
import org.springframework.security.crypto.password.passwordencoder;
import org.springframework.stereotype.service;

import java.util.arraylist;
import java.util.list;

/**
 * userdetailsservice定义了根据用户名加载用户特定数据的服务。
 * 当spring security进行身份验证时,它会使用userdetailsservice来获取用户的详细信息,
 * 这些详细信息将被封装在一个userdetails对象中。
 *
 * userdetailsservice接口中只有一个方法:loaduserbyusername
 *
 * 这个方法接受一个用户名作为参数,并返回一个userdetails对象,
 * 该对象包含了用户的详细信息,如用户名、密码、授权信息等。
 * 如果找不到与给定用户名对应的用户,该方法应该抛出usernamenotfoundexception异常。
 *
 * 在spring security的配置中,需要提供一个实现了userdetailsservice接口的bean。
 * 这个bean将负责根据用户名从数据库或其他用户存储中检索用户信息,并将其转换为userdetails对象。
 *
 */
@service
public class userdetailserviceimpl implements userdetailsservice {

    @autowired
    private passwordencoder passwordencoder;

    @override
    public userdetails loaduserbyusername(string username) throws usernamenotfoundexception {
        // 模拟根据用户名去数据库查询
        user user = getuserbyusername(username);
        if(user == null){
            throw new usernamenotfoundexception("用户名不存在");
        }

        // 密码需要加密,否则密码对比不一致会认证失败
        user.setpwd(passwordencoder.encode(user.getpwd()));

        userdetail userdetail = new userdetail();
        list<grantedauthority> authorities = new arraylist<>();
        // 设置对应权限
        authorities.add(()-> "admin");
        userdetail.setauthorities(authorities);
        userdetail.setuser(user);
        return userdetail;
    }


    private user getuserbyusername(string username){
        if("ttz".equals(username)){
            user user = new user();
            user.setusername("ttz");
            user.setpwd("980422");
            return user;
        }
        return null;
    }
}

到此这篇关于springsecurity自定义登录接口的实现的文章就介绍到这了,更多相关springsecurity自定义登录接口内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com