Browse Source

Merge branch 'dev' of http://192.168.1.220:10080/jiagou/jkzl-starter into dev

chenweida 6 years ago
parent
commit
92d0ac46c3

+ 12 - 1
common-security-starter/src/main/java/com.yihu.base.security/config/ResourceServerConfig.java

@ -1,7 +1,9 @@
package com.yihu.base.security.config;
import com.yihu.base.security.properties.SecurityProperties;
import com.yihu.base.security.rbas.UserServiceProvider;
import com.yihu.base.security.rbas.provider.AuthorizeConfigProviderManager;
import com.yihu.base.security.rbas.provider.UserNamePasswordAuthenticationProvider;
import com.yihu.base.security.sms.SmsCodeAuthenticationSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@ -10,6 +12,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
@ -46,6 +49,10 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    private OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler;
    @Autowired
    private LogoutSuccessHandler baseLogoutSuccessHandler;
    @Autowired
    private UserServiceProvider userServiceProvider;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public void configure(HttpSecurity http) throws Exception {
@ -64,7 +71,11 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                .and()
                    .apply(smsCodeAuthenticationSecurityConfig); //添加自定义短信登陆;
        UserNamePasswordAuthenticationProvider userNamePasswordAuthenticationProvider = new UserNamePasswordAuthenticationProvider();
        userNamePasswordAuthenticationProvider.setUserDetailsService(userServiceProvider);
        userNamePasswordAuthenticationProvider.setHideUserNotFoundExceptions(false);
        userNamePasswordAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        http.authenticationProvider(userNamePasswordAuthenticationProvider);
        //验证路径
        authorizeConfigProviderManager.config(http.authorizeRequests());
    }

+ 208 - 0
common-security-starter/src/main/java/com.yihu.base.security/rbas/provider/UserNamePasswordAuthenticationProvider.java

@ -0,0 +1,208 @@
package com.yihu.base.security.rbas.provider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
/**
 * Created by 刘文彬 on 2018/6/1.
 */
public class UserNamePasswordAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    // ~ Static fields/initializers
    // =====================================================================================
    /**
     * The plaintext password used to perform
     * {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
     * not found to avoid SEC-2056.
     */
    private static final String USER_NOT_FOUND_PASSWORD = "userNotFoundPassword";
    // ~ Instance fields
    // ================================================================================================
    private PasswordEncoder passwordEncoder;
    /**
     * The password used to perform
     * {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is
     * not found to avoid SEC-2056. This is necessary, because some
     * {@link PasswordEncoder} implementations will short circuit if the password is not
     * in a valid format.
     */
    private String userNotFoundEncodedPassword;
    private SaltSource saltSource;
    private UserDetailsService userDetailsService;
    public UserNamePasswordAuthenticationProvider() {
        setPasswordEncoder(new PlaintextPasswordEncoder());
    }
    // ~ Methods
    // ========================================================================================================
    @SuppressWarnings("deprecation")
    protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                  UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        Object salt = null;
        if (this.saltSource != null) {
            salt = this.saltSource.getSalt(userDetails);
        }
        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no credentials provided");
            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials",
                    "Bad credentials"));
        }
        String presentedPassword = authentication.getCredentials().toString();
        if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
                presentedPassword, salt)) {
            logger.debug("Authentication failed: password does not match stored value");
            throw new BadCredentialsException(messages.getMessage(
                    "AbstractUserDetailsAuthenticationProvider.badCredentials",
                    "Bad credentials"));
        }
    }
    protected void doAfterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
    }
    protected final UserDetails retrieveUser(String username,
                                             UsernamePasswordAuthenticationToken authentication)
            throws UsernameNotFoundException {
        UserDetails loadedUser;
        try {
            loadedUser = this.getUserDetailsService().loadUserByUsername(username);
        }
        catch (UsernameNotFoundException notFound) {
//            if (authentication.getCredentials() != null) {
//                String presentedPassword = authentication.getCredentials().toString();
//                passwordEncoder.isPasswordValid(userNotFoundEncodedPassword,
//                        presentedPassword, null);
//            }
            throw notFound;
        }
        catch (Exception repositoryProblem) {
            throw new InternalAuthenticationServiceException(
                    repositoryProblem.getMessage(), repositoryProblem);
        }
        if (loadedUser == null) {
            throw new InternalAuthenticationServiceException(
                    "UserDetailsService returned null, which is an interface contract violation");
        }
        return loadedUser;
    }
    /**
     * Sets the PasswordEncoder instance to be used to encode and validate passwords. If
     * not set, the password will be compared as plain text.
     * <p>
     * For systems which are already using salted password which are encoded with a
     * previous release, the encoder should be of type
     * {@code org.springframework.security.authentication.encoding.PasswordEncoder}.
     * Otherwise, the recommended approach is to use
     * {@code org.springframework.security.crypto.password.PasswordEncoder}.
     *
     * @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
     * types.
     */
    public void setPasswordEncoder(Object passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        if (passwordEncoder instanceof PasswordEncoder) {
            setPasswordEncoder((PasswordEncoder) passwordEncoder);
            return;
        }
        if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) {
            final org.springframework.security.crypto.password.PasswordEncoder delegate = (org.springframework.security.crypto.password.PasswordEncoder) passwordEncoder;
            setPasswordEncoder(new PasswordEncoder() {
                public String encodePassword(String rawPass, Object salt) {
                    checkSalt(salt);
                    return delegate.encode(rawPass);
                }
                public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
                    checkSalt(salt);
                    return delegate.matches(rawPass, encPass);
                }
                private void checkSalt(Object salt) {
                    Assert.isNull(salt,
                            "Salt value must be null when used with crypto module PasswordEncoder");
                }
            });
            return;
        }
        throw new IllegalArgumentException(
                "passwordEncoder must be a PasswordEncoder instance");
    }
    private void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");
        this.userNotFoundEncodedPassword = passwordEncoder.encodePassword(
                USER_NOT_FOUND_PASSWORD, null);
        this.passwordEncoder = passwordEncoder;
    }
    protected PasswordEncoder getPasswordEncoder() {
        return passwordEncoder;
    }
    /**
     * The source of salts to use when decoding passwords. <code>null</code> is a valid
     * value, meaning the <code>DaoAuthenticationProvider</code> will present
     * <code>null</code> to the relevant <code>PasswordEncoder</code>.
     * <p>
     * Instead, it is recommended that you use an encoder which uses a random salt and
     * combines it with the password field. This is the default approach taken in the
     * {@code org.springframework.security.crypto.password} package.
     *
     * @param saltSource to use when attempting to decode passwords via the
     * <code>PasswordEncoder</code>
     */
    public void setSaltSource(SaltSource saltSource) {
        this.saltSource = saltSource;
    }
    protected SaltSource getSaltSource() {
        return saltSource;
    }
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
    protected UserDetailsService getUserDetailsService() {
        return userDetailsService;
    }
}

+ 13 - 8
demo/demo-lwb/pom.xml

@ -13,11 +13,11 @@
    <artifactId>demo-lwb</artifactId>
    <dependencies>
        <!--<dependency>-->
            <!--<groupId>com.yihu</groupId>-->
            <!--<artifactId>common-security-starter</artifactId>-->
            <!--<version>1.0.1</version>-->
        <!--</dependency>-->
        <dependency>
            <groupId>com.yihu</groupId>
            <artifactId>common-security-starter</artifactId>
            <version>1.0.7</version>
        </dependency>
        <dependency>
            <groupId>com.yihu</groupId>
            <artifactId>common-swagger-starter</artifactId>
@ -29,9 +29,9 @@
            <version>1.1.0</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>com.yihu</groupId>-->
            <!--<artifactId>common-data-es-starter</artifactId>-->
            <!--<version>1.1.0</version>-->
        <!--<groupId>com.yihu</groupId>-->
        <!--<artifactId>common-data-es-starter</artifactId>-->
        <!--<version>1.1.0</version>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
@ -66,6 +66,11 @@
            <artifactId>spring-security-core</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.yihu.jw</groupId>
            <artifactId>common-rest-model</artifactId>
            <version>1.0.2</version>
        </dependency>
    </dependencies>
    <build>

+ 6 - 3
demo/demo-lwb/src/main/java/com/demo/config/SwaggerConfig.java

@ -6,6 +6,7 @@ import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
@ -26,7 +27,8 @@ import static springfox.documentation.builders.PathSelectors.regex;
public class SwaggerConfig {
    public static final String system_API = "system"; //系统相关
    @Autowired
    private Docket docket;
    @Bean
    public Docket systemAPI() {
@ -40,7 +42,8 @@ public class SwaggerConfig {
                        regex("/system/.*"),
                        regex("/demo/.*"),
                        regex("/route/.*"),
                        regex("/security/.*")
                        regex("/login/.*"),
                        regex("/tokens/.*")
                ))
                .build()
                .apiInfo(systemApiInfo());
@ -67,7 +70,7 @@ public class SwaggerConfig {
     */
    public static void main(String[] args) throws Exception {
        String groupName="openAPI";
       // String groupName="iot";
        // String groupName="iot";
        URL remoteSwaggerFile = new URL("http://127.0.0.1:8080//v2/api-docs?group="+groupName);
        Path outputFile = Paths.get("open-api/build/"+groupName);

+ 3 - 4
demo/demo-lwb/src/main/java/com/demo/controller/SecurityController.java

@ -2,7 +2,6 @@ package com.demo.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@ -23,7 +22,7 @@ import java.util.UUID;
 * Created by Administrator on 2018/4/3 0003.
 */
@RestController
@RequestMapping("/security")
@RequestMapping("/login")
@Api(tags = "登陆相关", description = "登陆相关demo")
public class SecurityController {
@ -47,13 +46,13 @@ public class SecurityController {
            //  封装参数,千万不要替换为Map与HashMap,否则参数无法传递
            MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
            //  也支持中文
            params.add("username", "admin");
            params.add("username", "admin11");
            params.add("password", "123456");
            //设置http请求实体
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
            result = restTemplate.postForObject("http://localhost:8080/authentication/form", requestEntity, String.class);
            result = restTemplate.postForObject("http://localhost:8081/authentication/form", requestEntity, String.class);
        } catch (Exception e) {

+ 18 - 18
demo/demo-lwb/src/main/java/com/demo/service/RBASService.java

@ -1,18 +1,18 @@
//package com.demo.service;
//
//import com.yihu.base.security.rbas.RbasServiceProvider;
//import org.springframework.security.core.Authentication;
//import org.springframework.stereotype.Component;
//
//import javax.servlet.http.HttpServletRequest;
//
///**
// * Created by Administrator on 2018/4/3 0003.
// */
//@Component("rbasServiceProvider")
//public class RBASService implements RbasServiceProvider {
//    @Override
//    public Boolean hasPerssion(HttpServletRequest request, Authentication authentication) {
//        return true;
//    }
//}
package com.demo.service;
import com.yihu.base.security.rbas.RbasServiceProvider;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
 * Created by Administrator on 2018/4/3 0003.
 */
@Component("rbasServiceProvider")
public class RBASService implements RbasServiceProvider {
    @Override
    public Boolean hasPerssion(HttpServletRequest request, Authentication authentication) {
        return true;
    }
}

+ 50 - 44
demo/demo-lwb/src/main/java/com/demo/service/UserService.java

@ -1,44 +1,50 @@
//package com.demo.service;
//
//import com.yihu.base.security.rbas.ClientServiceProvider;
//import com.yihu.base.security.rbas.UserServiceProvider;
//import org.springframework.beans.factory.annotation.Autowired;
//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.UsernameNotFoundException;
//import org.springframework.security.crypto.password.PasswordEncoder;
//import org.springframework.security.oauth2.provider.ClientDetails;
//import org.springframework.security.oauth2.provider.ClientRegistrationException;
//import org.springframework.security.oauth2.provider.client.BaseClientDetails;
//import org.springframework.stereotype.Component;
//
//import java.util.ArrayList;
//
///**
// * Created by Administrator on 2018/4/3 0003.
// */
//@Component
//public class UserService implements ClientServiceProvider, UserServiceProvider {
//    @Autowired
//    private PasswordEncoder passwordEncoder;
//
//    @Override
//    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
//        BaseClientDetails baseClientDetails = new BaseClientDetails();
//        baseClientDetails.setClientId("client_id");
//        baseClientDetails.setClientSecret("client_secret");
//        return baseClientDetails;
//    }
//
//    @Override
//    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        return new User("admin",
//                    passwordEncoder.encode("123456"),
//                    true,
//                    true,
//                    true,
//                    true
//                    , AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER")); //权限
//    }
//}
package com.demo.service;
import com.yihu.base.security.rbas.ClientServiceProvider;
import com.yihu.base.security.rbas.UserServiceProvider;
import com.yihu.base.security.vo.MyUsernameNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
/**
 * Created by Administrator on 2018/4/3 0003.
 */
@Component
public class UserService implements ClientServiceProvider, UserServiceProvider {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
        BaseClientDetails baseClientDetails = new BaseClientDetails();
        baseClientDetails.setClientId("client_id");
        baseClientDetails.setClientSecret("client_secret");
        return baseClientDetails;
    }
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(!"admin".equals(username)){
            throw new MyUsernameNotFoundException("账户不存在");
        }
        return new User("admin",
                passwordEncoder.encode("123456"),
                true,
                true,
                true,
                true
                , AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_USER")); //权限
    }
}