zoukankan      html  css  js  c++  java
  • SpringSecurity自定义用户登录

    根据上一节的配置,默认在服务开启的时候会被要求自动的进行表单登陆。用到的用户名只能是一个固定的用户名user,它的密码是每次启动的时候服务器自动生成的。最常见的场景是我们的用户是从数据库中获取的。

    1.处理用户信息获取逻辑

    import org.slf4j.LoggerFactory;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Component;
    import java.util.logging.Logger;
    //自定义用户处理的逻辑
    //用户的信息的service
    @Component
    public class MyUserDetailService implements UserDetailsService {
        /**
         * 日志处理类
         */
        private org.slf4j.Logger logger =  LoggerFactory.getLogger(this.getClass());
        /**
         * 根据用户名加载用户信息
         *
         * @param username 用户名
         * @return UserDetails
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            logger.info("表单登录用户名:" + username);
            System.out.println("表单登录用户名:" + username);
            return new User(username,"123456",true,
                    true,
                    true,
                    true,
                    AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        }
    }
    
    

    这里我们用的security里面的User进行存放,但是我们这边存放的密码是明文"123456",接下来会报错(没有用它的加密):

    image.png

    需要注意的是 在这里用了Spring默认的一个类User,在自己的实现过程中并不一定要用Spring的类
    可以自己定义一个对象实现UserDetail接口。

    public class User implements  UserDetails,CredentialsContrain{}
    

    2.加密用户的登录

    注意在注入PasswordEncoder之前我们要在继承了WebSecurityConfigurerAdapter的类中注入并产生PasswordEncoder接口的实现类:

    @Configuration
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Bean
        public PasswordEncoder passwordEncoder(){
            return  new BCryptPasswordEncoder();
        }
    
    ........这里是省略掉之前覆写了的方法
      
    }
    

    我们来修改下MyUserDetailService,如下:

    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.userdetails.User;
    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.Component;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.logging.Logger;
    
    //自定义用户处理的逻辑
    //用户的信息的service
    @Component
    public class MyUserDetailService implements UserDetailsService {
        /**
         * 日志处理类
         */
        private org.slf4j.Logger logger =  LoggerFactory.getLogger(this.getClass());
        @Autowired
        private PasswordEncoder passwordEncoder;
        /**
         * 根据用户名加载用户信息
         *
         * @param username 用户名
         * @return UserDetails
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            logger.info("表单登录用户名:" + username);
            System.out.println("表单登录用户名:" + username);
            List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
            grantedAuthorityList.add(new GrantedAuthority() {
                @Override
                public String getAuthority() {
                    return "admin";
                }
            });
    
            String pWord =passwordEncoder.encode("123");
            System.out.println("表单登录密码:" + pWord);
            logger.info(pWord);
            return new User("test",pWord,true,
                    true,
                    true,
                    true,
                    AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        }
    }
    
    

    启动 使用test:123 即可登录成功

    3.放入自定义User对象

    MyUser:

    package urity.demo.support;
    
    import org.springframework.security.core.CredentialsContainer;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.SpringSecurityCoreVersion;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.util.Assert;
    
    import java.io.Serializable;
    import java.util.*;
    @Slf4j
    public class MyUser implements UserDetails, CredentialsContainer {
    
    
    
    
            private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
    
            // ~ Instance fields
            // ================================================================================================
            private String password;
            private  String username;
            private final Set<GrantedAuthority> authorities;
            private final boolean accountNonExpired;
            private final boolean accountNonLocked;
            private final boolean credentialsNonExpired;
            private final boolean enabled;
    
            // ~ Constructors
            // ===================================================================================================
    
            /**
             * Calls the more complex constructor with all boolean arguments set to {@code true}.
             */
            public MyUser(String username, String password,
                                     Collection<? extends GrantedAuthority> authorities) {
                this(username, password, true, true, true, true, authorities);
            }
    
            /**
             * Construct the <code>User</code> with the details required by
             * {@link org.springframework.security.authentication.dao.DaoAuthenticationProvider}.
             *
             * @param username the username presented to the
             * <code>DaoAuthenticationProvider</code>
             * @param password the password that should be presented to the
             * <code>DaoAuthenticationProvider</code>
             * @param enabled set to <code>true</code> if the user is enabled
             * @param accountNonExpired set to <code>true</code> if the account has not expired
             * @param credentialsNonExpired set to <code>true</code> if the credentials have not
             * expired
             * @param accountNonLocked set to <code>true</code> if the account is not locked
             * @param authorities the authorities that should be granted to the caller if they
             * presented the correct username and password and the user is enabled. Not null.
             *
             * @throws IllegalArgumentException if a <code>null</code> value was passed either as
             * a parameter or as an element in the <code>GrantedAuthority</code> collection
             */
            public MyUser(String username, String password, boolean enabled,
                                     boolean accountNonExpired, boolean credentialsNonExpired,
                                     boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
    
                if (((username == null) || "".equals(username)) || (password == null)) {
                    throw new IllegalArgumentException(
                            "Cannot pass null or empty values to constructor");
                }
    
                this.username = username;
                this.password = password;
                this.enabled = enabled;
                this.accountNonExpired = accountNonExpired;
                this.credentialsNonExpired = credentialsNonExpired;
                this.accountNonLocked = accountNonLocked;
                this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities));
            }
    
    
        public void setMyUserDetails(urity.demo.entity.User user){
            this.username = user.getUsername();
            this.password = user.getPassword();
        }
            // ~ Methods
            // ========================================================================================================
    
            public Collection<GrantedAuthority> getAuthorities() {
                return authorities;
            }
    
            public String getPassword() {
                return password;
            }
    
            public String getUsername() {
                return username;
            }
    
            public boolean isEnabled() {
                return enabled;
            }
    
            public boolean isAccountNonExpired() {
                return accountNonExpired;
            }
    
            public boolean isAccountNonLocked() {
                return accountNonLocked;
            }
    
            public boolean isCredentialsNonExpired() {
                return credentialsNonExpired;
            }
    
            public void eraseCredentials() {
                password = null;
            }
    
            private static SortedSet<GrantedAuthority> sortAuthorities(
                    Collection<? extends GrantedAuthority> authorities) {
                Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection");
                // Ensure array iteration order is predictable (as per
                // UserDetails.getAuthorities() contract and SEC-717)
                SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<GrantedAuthority>(
                        new MyUser.AuthorityComparator());
    
                for (GrantedAuthority grantedAuthority : authorities) {
                    Assert.notNull(grantedAuthority,
                            "GrantedAuthority list cannot contain any null elements");
                    sortedAuthorities.add(grantedAuthority);
                }
    
                return sortedAuthorities;
            }
    
            private static class AuthorityComparator implements Comparator<GrantedAuthority>,
                    Serializable {
                private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
    
                public int compare(GrantedAuthority g1, GrantedAuthority g2) {
                    // Neither should ever be null as each entry is checked before adding it to
                    // the set.
                    // If the authority is null, it is a custom authority and should precede
                    // others.
                    if (g2.getAuthority() == null) {
                        return -1;
                    }
    
                    if (g1.getAuthority() == null) {
                        return 1;
                    }
    
                    return g1.getAuthority().compareTo(g2.getAuthority());
                }
            }
    
            /**
             * Returns {@code true} if the supplied object is a {@code User} instance with the
             * same {@code username} value.
             * <p>
             * In other words, the objects are equal if they have the same username, representing
             * the same principal.
             */
            @Override
            public boolean equals(Object rhs) {
                if (rhs instanceof MyUser) {
                    return username.equals(((MyUser) rhs).username);
                }
                return false;
            }
    
            /**
             * Returns the hashcode of the {@code username}.
             */
            @Override
            public int hashCode() {
                return username.hashCode();
            }
    
            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder();
                sb.append(super.toString()).append(": ");
                sb.append("Username: ").append(this.username).append("; ");
                sb.append("Password: [PROTECTED]; ");
                sb.append("Enabled: ").append(this.enabled).append("; ");
                sb.append("AccountNonExpired: ").append(this.accountNonExpired).append("; ");
                sb.append("credentialsNonExpired: ").append(this.credentialsNonExpired)
                        .append("; ");
                sb.append("AccountNonLocked: ").append(this.accountNonLocked).append("; ");
    
                if (!authorities.isEmpty()) {
                    sb.append("Granted Authorities: ");
    
                    boolean first = true;
                    for (GrantedAuthority auth : authorities) {
                        if (!first) {
                            sb.append(",");
                        }
                        first = false;
    
                        sb.append(auth);
                    }
                }
                else {
                    sb.append("Not granted any authorities");
                }
    
                return sb.toString();
            }
    
            public static MyUser.UserBuilder withUsername(String username) {
                return new MyUser.UserBuilder().username(username);
            }
    
            /**
             * Builds the user to be added. At minimum the username, password, and authorities
             * should provided. The remaining attributes have reasonable defaults.
             */
            public static class UserBuilder {
                private String username;
                private String password;
                private List<GrantedAuthority> authorities;
                private boolean accountExpired;
                private boolean accountLocked;
                private boolean credentialsExpired;
                private boolean disabled;
    
                /**
                 * Creates a new instance
                 */
                private UserBuilder() {
                }
    
                /**
                 * Populates the username. This attribute is required.
                 *
                 * @param username the username. Cannot be null.
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                private MyUser.UserBuilder username(String username) {
                    Assert.notNull(username, "username cannot be null");
                    this.username = username;
                    return this;
                }
    
                /**
                 * Populates the password. This attribute is required.
                 *
                 * @param password the password. Cannot be null.
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder password(String password) {
                    Assert.notNull(password, "password cannot be null");
                    this.password = password;
                    return this;
                }
    
                /**
                 * Populates the roles. This method is a shortcut for calling
                 * {@link #authorities(String...)}, but automatically prefixes each entry with
                 * "ROLE_". This means the following:
                 *
                 * <code>
                 *     builder.roles("USER","ADMIN");
                 * </code>
                 *
                 * is equivalent to
                 *
                 * <code>
                 *     builder.authorities("ROLE_USER","ROLE_ADMIN");
                 * </code>
                 *
                 * <p>
                 * This attribute is required, but can also be populated with
                 * {@link #authorities(String...)}.
                 * </p>
                 *
                 * @param roles the roles for this user (i.e. USER, ADMIN, etc). Cannot be null,
                 * contain null values or start with "ROLE_"
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder roles(String... roles) {
                    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(
                            roles.length);
                    for (String role : roles) {
                        Assert.isTrue(!role.startsWith("ROLE_"), role
                                + " cannot start with ROLE_ (it is automatically added)");
                        authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
                    }
                    return authorities(authorities);
                }
    
                /**
                 * Populates the authorities. This attribute is required.
                 *
                 * @param authorities the authorities for this user. Cannot be null, or contain
                 * null values
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 * @see #roles(String...)
                 */
                public MyUser.UserBuilder authorities(GrantedAuthority... authorities) {
                    return authorities(Arrays.asList(authorities));
                }
    
                /**
                 * Populates the authorities. This attribute is required.
                 *
                 * @param authorities the authorities for this user. Cannot be null, or contain
                 * null values
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 * @see #roles(String...)
                 */
                public MyUser.UserBuilder authorities(List<? extends GrantedAuthority> authorities) {
                    this.authorities = new ArrayList<GrantedAuthority>(authorities);
                    return this;
                }
    
                /**
                 * Populates the authorities. This attribute is required.
                 *
                 * @param authorities the authorities for this user (i.e. ROLE_USER, ROLE_ADMIN,
                 * etc). Cannot be null, or contain null values
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 * @see #roles(String...)
                 */
                public MyUser.UserBuilder authorities(String... authorities) {
                    return authorities(AuthorityUtils.createAuthorityList(authorities));
                }
    
                /**
                 * Defines if the account is expired or not. Default is false.
                 *
                 * @param accountExpired true if the account is expired, false otherwise
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder accountExpired(boolean accountExpired) {
                    this.accountExpired = accountExpired;
                    return this;
                }
    
                /**
                 * Defines if the account is locked or not. Default is false.
                 *
                 * @param accountLocked true if the account is locked, false otherwise
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder accountLocked(boolean accountLocked) {
                    this.accountLocked = accountLocked;
                    return this;
                }
    
                /**
                 * Defines if the credentials are expired or not. Default is false.
                 *
                 * @param credentialsExpired true if the credentials are expired, false otherwise
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder credentialsExpired(boolean credentialsExpired) {
                    this.credentialsExpired = credentialsExpired;
                    return this;
                }
    
                /**
                 * Defines if the account is disabled or not. Default is false.
                 *
                 * @param disabled true if the account is disabled, false otherwise
                 * @return the {@link User.UserBuilder} for method chaining (i.e. to populate
                 * additional attributes for this user)
                 */
                public MyUser.UserBuilder disabled(boolean disabled) {
                    this.disabled = disabled;
                    return this;
                }
    
                public UserDetails build() {
                    return new User(username, password, !disabled, !accountExpired,
                            !credentialsExpired, !accountLocked, authorities);
                }
            }
    
    
    
    
        }
    
    
    
    
    

    MyUserDetailService:

    package urity.demo.support;
    
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.AuthorityUtils;
    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.Component;
    import urity.demo.entity.User;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.logging.Logger;
    
    //自定义用户处理的逻辑
    //用户的信息的service
    @Component
    public class MyUserDetailService implements UserDetailsService {
        /**
         * 日志处理类
         */
        private org.slf4j.Logger logger =  LoggerFactory.getLogger(this.getClass());
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
    
        /**
         * 根据用户名加载用户信息
         *
         * @param username 用户名
         * @return UserDetails
         * @throws UsernameNotFoundException
         */
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            logger.info("表单登录用户名:" + username);
            System.out.println("表单登录用户名:" + username);
            List<GrantedAuthority> grantedAuthorityList = new ArrayList<>();
            grantedAuthorityList.add(new GrantedAuthority() {
                @Override
                public String getAuthority() {
                    return "admin";
                }
            });
    
           User user = new User();
           user.setUsername("test");
           user.setPassword("123");
    
            String pWord =passwordEncoder.encode(user.getPassword());
            System.out.println("表单登录密码:" + pWord);
    
            MyUser myUser = new MyUser(username,pWord,AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER"));
    
    
            return myUser;
        }
    }
    
    

    启动后和刚才一样进行认证即可.

  • 相关阅读:
    C# Thread Lambda
    C#中Invoke的用法
    C#抽象类和抽象方法
    SQL Server2005杂谈(2):公用表表达式(CTE)的递归调用
    改变自己的128种方法
    小技巧
    Linux学习第一章作业.zxs
    Linux学习第二、三章作业.zxs
    Linux 系统管理 04—账号管理
    Mysql中的in和find_in_set的区别?
  • 原文地址:https://www.cnblogs.com/charlypage/p/9320520.html
Copyright © 2011-2022 走看看