91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring如何配置自定義的用戶存儲

發布時間:2022-10-18 16:05:13 來源:億速云 閱讀:119 作者:iii 欄目:編程語言

這篇文章主要講解了“Spring如何配置自定義的用戶存儲”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring如何配置自定義的用戶存儲”吧!

配置自定義的用戶存儲

通過查看AuthenticationManagerBuilder的源碼可以發現里面還有一個方法 userDetailsService(),允許我們自定義用戶存儲的實現.如下

/**
     * Add authentication based upon the custom {@link UserDetailsService} that is passed
     * in. It then returns a {@link DaoAuthenticationConfigurer} to allow customization of
     * the authentication.
     *
     * <p>
     * This method also ensure that the {@link UserDetailsService} is available for the
     * {@link #getDefaultUserDetailsService()} method. Note that additional
     * {@link UserDetailsService}'s may override this {@link UserDetailsService} as the
     * default.
     * </p>
     *
     * @return a {@link DaoAuthenticationConfigurer} to allow customization of the DAO
     * authentication
     * @throws
    public <T extends UserDetailsService> DaoAuthenticationConfigurer<AuthenticationManagerBuilder, T> userDetailsService(
            T userDetailsService) throws Exception {
        this.defaultUserDetailsService = userDetailsService;
        return apply(new

我們發現 此方法接收一個 UserDetailsService 的實現類.我們可以再點進去查看一下 UserDetailsService 的源碼,如下:

/**
 * Core interface which loads user-specific data.
 * <p>
 * It is used throughout the framework as a user DAO and is the strategy used by the
 * {@link org.springframework.security.authentication.dao.DaoAuthenticationProvider
 * DaoAuthenticationProvider}.
 *
 * <p>
 * The interface requires only one read-only method, which simplifies support for new
 * data-access strategies.
 *
 * @see org.springframework.security.authentication.dao.DaoAuthenticationProvider
 * @see UserDetails
 *
 * @author
public interface UserDetailsService
    // ~ Methods
    // ========================================================================================================

    /**
     * Locates the user based on the username. In the actual implementation, the search
     * may possibly be case sensitive, or case insensitive depending on how the
     * implementation instance is configured. In this case, the <code>UserDetails</code>
     * object that comes back may have a username that is of a different case than what
     * was actually requested..
     *
     * @param username the username identifying the user whose data is required.
     *
     * @return a fully populated user record (never <code>null</code>)
     *
     * @throws
    UserDetails loadUserByUsername(String username) throws

發現這是一個接口,并且只有一個方法 loadUserByUsername(),我們所需要做的就是實現loadUserByUsername()方法,根據給定的用戶名來查找用戶。
loadUserByUsername()方法會返回代表給定用戶的UserDetails對象.

而這個UserDetail 又是個什么呢?我們再次產看其源碼,如下:

/**
 * Provides core user information.
 *
 * <p>
 * Implementations are not used directly by Spring Security for security purposes. They
 * simply store user information which is later encapsulated into {@link Authentication}
 * objects. This allows non-security related user information (such as email addresses,
 * telephone numbers etc) to be stored in a convenient location.
 * <p>
 * Concrete implementations must take particular care to ensure the non-null contract
 * detailed for each method is enforced. See
 * {@link org.springframework.security.core.userdetails.User} for a reference
 * implementation (which you might like to extend or use in your code).
 *
 * @see UserDetailsService
 * @see UserCache
 *
 * @author
public interface UserDetails extends Serializable
    // ~ Methods
    // ========================================================================================================

    /**
     * Returns the authorities granted to the user. Cannot return <code>null</code>.
     *
     * @return
    Collection<? extends GrantedAuthority> getAuthorities();

    /**
     * Returns the password used to authenticate the user.
     *
     * @return
    String getPassword();

    /**
     * Returns the username used to authenticate the user. Cannot return <code>null</code>
     * .
     *
     * @return
    String getUsername();

    /**
     * Indicates whether the user's account has expired. An expired account cannot be
     * authenticated.
     *
     * @return
    boolean isAccountNonExpired();

    /**
     * Indicates whether the user is locked or unlocked. A locked user cannot be
     * authenticated.
     *
     * @return
    boolean isAccountNonLocked();

    /**
     * Indicates whether the user's credentials (password) has expired. Expired
     * credentials prevent authentication.
     *
     * @return
    boolean isCredentialsNonExpired();

    /**
     * Indicates whether the user is enabled or disabled. A disabled user cannot be
     * authenticated.
     *
     * @return
    boolean

發現這也是一個接口,也就是說我們還要實現這個 UserDetail接口.這個結構封裝了用戶的登陸信息.

好了,了解了 userDetailsService 方法的構造,我們就可以著手寫代碼了.

首先定義一個 MyUserService 實現 UserDetailsService 接口.并在重寫的 loadUserByUsername 方法中返回 UserDetail類型的對象即可,
代碼如下:

/**
 * 自定義用戶實現
 *
 * @author itguang
 * @create
public class MyUserService implements UserDetailsService


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



        //自定義用戶存儲數據來源,可以是從關系型數據庫,非關系性數據庫,或者其他地方獲取用戶數據。
        UserEntity userEntity = new UserEntity("itguang", "123456", true);

        //還可以在此設置賬號的鎖定,過期,憑據失效 等參數
        //...

        // 設置 權限,可以是從數據庫中查找出來的
        ArrayList<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));


        userEntity.setAuthorities(authorities);

        return

可以看到我們最后返回了一個 UserEntity 對象,這個類是我們自定義的 對UserDetail接口的實現類,代碼如下:

/**
 * @author itguang
 * @create

@Data
public class UserEntity implements UserDetails{


    /**
     * 用戶名
     */
    private String username;

    /**
     * 密碼
     */
    private String password;

    /**
     * 是否可用
     */
    private Boolean enabled;

    /**
     *用戶所擁有的權限
     */
    private List<? extends GrantedAuthority> authorities;

    /**
     * 用戶的賬號是否過期,過期的賬號無法通過授權驗證. true 賬號未過期
     */
    private Boolean accountNonExpired = true;

    /**
     * 用戶的賬戶是否被鎖定,被鎖定的賬戶無法通過授權驗證. true 賬號未鎖定
     */
    private Boolean accountNonLocked = true;

    /**
     * 用戶的憑據(pasword) 是否過期,過期的憑據不能通過驗證. true 沒有過期,false 已過期
     */
    private Boolean credentialsNonExpired = true;

    public UserEntity(String username, String password, Boolean enabled) {
        this.username = username;
        this.password = password;
        this.enabled = enabled;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return

為什么我們要這樣寫呢,其實莫慌,我們如果不像自己實現 UserDetails 接口,Spring Security 已經為我們實現好了.我們來到 UserDetails接口,
把鼠標放到 UserDetails 上,在idea下按 ctrl+h ,我們就可以看到這個接口的實現類,如圖:

除了我們自定義的UserEntity外,還有一個 User,其實這就是Spring Security為我們實現好的 UserDetails 類.我們可以看到它的源碼如下:

public class User implements UserDetails, CredentialsContainer

    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

    // ~ Instance fields
    // ================================================================================================
    private String password;
    private final String username;
    private final Set<GrantedAuthority> authorities;
    private final boolean accountNonExpired;
    private final boolean accountNonLocked;
    private final boolean credentialsNonExpired;
    private final boolean enabled;

    //...

由于源碼太長,這里只貼出一部分,可以看到這里面也有我們在UserEntity定義的字段.其實也不奇怪了,本來我們的 UserEntity 就是按著User進行改造的嘛.

之所以自定義UserEntity,這里是為了方面初學者進行快速入門,相比于User我們的UserEntity還是很簡單的.

現在 我們的 UserDetailsService 已經完成了,接下來就是在 SecurityConfig 的configure方法中使用了,如下:

/**
 * 自定義用戶存儲
 *
 * @author itguang
 * @create
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new

怎么樣是不是很簡單.

測試.

最后進行測試,運行項目,訪問: http://localhost/hello ,會跳轉到 http://localhost/login 讓我們登陸,我們是輸入 用戶名 itguang 和密碼 123456

點擊登錄,就會看到瀏覽器返回一個 hello Spring Security ,說明我們自定義用戶存儲已經完美實現.

感謝各位的閱讀,以上就是“Spring如何配置自定義的用戶存儲”的內容了,經過本文的學習后,相信大家對Spring如何配置自定義的用戶存儲這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天门市| 清水县| 安泽县| 西华县| 华安县| 新闻| 资源县| 栾川县| 阿拉尔市| 轮台县| 泰州市| 宾川县| 沁源县| 浏阳市| 孙吴县| 贞丰县| 南开区| 望都县| 河曲县| 宁武县| 昌平区| 东丰县| 汾西县| 抚宁县| 贺兰县| 桑植县| 广饶县| 平定县| 渝北区| 灵山县| 手机| 石城县| 南投县| 名山县| 正镶白旗| 峨眉山市| 青州市| 遂溪县| 宝清县| 四川省| 格尔木市|