SpringBoot实例:医院统一信息平台(单点登录测试)

前面已经完成了Oauth2服务器的开发,简单测试了下access_token的获取。spring security oauth还支持SSO单点登录服务端与客户端。我们现在做的是用户系统,调整一下代码,做SSO服务端。

授权页面

增加一个授权页面,在用户在别的系统中登录的时候询问用户是否允许系统向用户系统取某些信息。




    
    授权


    

程序想要请您授权以下内容:

Some Scope

请许可上述授权范围并点击确认并授权按钮继续。

授权控制器

在com.biboheart.huip.user.security.controller创建SecurityController.java文件。主要实现用户信息获取,用户权限获取等接口。授权页面的控制器也放在这里

package com.biboheart.huip.user.security.controller;

import java.security.Principal;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.security.oauth2.provider.approval.Approval;
import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.biboheart.brick.model.BhResponseResult;

@Controller
@SessionAttributes("authorizationRequest")
public class SecurityController {
    @Autowired
    private ApprovalStore approvalStore;
    
    @RequestMapping(value = "/user/info")
    @ResponseBody
    public ResponseEntity user(Principal principal) {
        return new ResponseEntity<>(principal, HttpStatus.OK);
    }
    
    @RequestMapping(value = "/user/name")
    @ResponseBody
    public String username(Principal principal) {
        return principal.getName();
    }
    
    @RequestMapping(value = "/user/authorities")
    @ResponseBody
    public BhResponseResult authorities(Principal principal) {
        Collection authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        return new BhResponseResult<>(0, "操作成功", authorities);
    }
    
    @RequestMapping("/oauth/confirm_access")
    public ModelAndView getAccessConfirmation(Map model, Principal principal) {
        AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
        model.put("auth_request", clientAuth);
        model.put("client", "client");
        Map scopes = new LinkedHashMap();
        for (String scope : clientAuth.getScope()) {
            scopes.put(OAuth2Utils.SCOPE_PREFIX + scope, "false");
        }
        for (Approval approval : approvalStore.getApprovals(principal.getName(), "client")) {
            if (clientAuth.getScope().contains(approval.getScope())) {
                scopes.put(OAuth2Utils.SCOPE_PREFIX + approval.getScope(),
                        approval.getStatus() == ApprovalStatus.APPROVED ? "true" : "false");
            }
        }
        model.put("scopes", scopes);
        System.out.println(model);
        return new ModelAndView("access_confirmation", model);
    }
}

调整配置

SecurityConfiguration.java中增加放行的point


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home", "/oauth/token", "/oauth/authorize").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
        http.addFilterBefore(mobileCodeAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
        // @formatter:on
    }

修改AuthorizationServerConfiguration

package com.biboheart.huip.user.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenStore tokenStore;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("client")
            .secret(new BCryptPasswordEncoder().encode("secret"))
            .authorizedGrantTypes("client_credentials", "password", "refresh_token", "authorization_code")
            .scopes("all", "user_info")
            .autoApprove(false) // true: 不会跳转到授权页面
            .redirectUris("http://localhost:8080/login");
    }
    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
            .authenticationManager(this.authenticationManager)
            .tokenStore(tokenStore);
    }
    
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer)
            throws Exception {
        oauthServer
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("isAuthenticated()");
    }
    
    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }
    
    @Bean
    public ApprovalStore approvalStore() {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);
        return store;
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

如果autoApprove设置为true的话,客户端就不会进入用户授权页面。对于本系统的客户端就不需要用户确认授权操作,这时候设置为true就行。现在我们是要测试授权页面的。所以设置为false

创建客户端

创建项目dssoclient,因为这个项目源码是不上传的,所以把项目中每个文件的代码都会贴入。
目录结构:


SpringBoot实例:医院统一信息平台(单点登录测试)_第1张图片
目录结构

pom.xml



    4.0.0
    
    
        com.biboheart.demos
        bootparent
        0.0.1-SNAPSHOT
    
    
    dssoclient
    dssoclient
    http://maven.apache.org
    
    
        UTF-8
    
    
    
        
            org.springframework.boot
            spring-boot-starter-security
        
        
        
            org.springframework.security.oauth
            spring-security-oauth2
            2.3.3.RELEASE
        
        
        
            org.springframework.security.oauth.boot
            spring-security-oauth2-autoconfigure
            2.0.0.RELEASE
        
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
    

DssoclientApplication

package com.biboheart.demo.dssoclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DssoclientApplication {
    public static void main(String[] args) {
        SpringApplication.run(DssoclientApplication.class, args);
    }
}

SecurityConfiguration

package com.biboheart.demo.dssoclient.security;

import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenProviderChain;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider;

@Configuration
@EnableOAuth2Sso
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2ClientContext oauth2ClientContext;
    
    @Bean
    public OAuth2RestTemplate oauth2RestTemplate(OAuth2ProtectedResourceDetails resource) {
        OAuth2RestTemplate template = new OAuth2RestTemplate(resource, oauth2ClientContext);

        AuthorizationCodeAccessTokenProvider authCodeProvider = new AuthorizationCodeAccessTokenProvider();
        authCodeProvider.setStateMandatory(false);
        AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(authCodeProvider));
        template.setAccessTokenProvider(provider);
        return template;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout().permitAll()
                .and()
            .httpBasic().disable();
        // @formatter:on
    }
    
}

HelloController

package com.biboheart.demo.dssoclient.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HelloController {
    
    @RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
    public String homePage() {
        return "index";
    }

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello";
    }
    
}

application.yml

server:
  port: 8080
spring:
  output:
    ansi:
      enabled: DETECT
  http:
    encoding:
      charset: UTF-8
    multipart:
      maxFileSize: -1
      maxRequestSize: 100MB
security:
  oauth2:
    client:
      clientId: client
      clientSecret: secret
      accessTokenUri: http://192.168.2.105:8180/oauth/token
      userAuthorizationUri: http://192.168.2.105:8180/oauth/authorize
      #tokenName: access_token
      #authenticationScheme: query
      #clientAuthenticationScheme: form
      #以下两行为自定义回调地址
      #pre-established-redirect-uri: http://localhost:8080/hello
      #use-current-uri: false
    resource:
      userInfoUri: http://192.168.2.105:8180/user/info
      #tokenInfoUri: http://192.168.2.105:8180/oauth/check_token
      #prefer-token-info: false
    basic:
      enabled: false
# LOGGING
logging:
  level:
    root: info

index.html




    
    Spring Security入门


    

欢迎使用Spring Security!

点击 这里 打个招呼吧

hello.html




    
    Hello World!


    

Hello world!

login.html没有使用

测试项目

运行用户系统(服务端项目)
运行dssoclient项目(客户端项目)
访问http://localhost:8080 客户端项目的首页,首页不受控制

SpringBoot实例:医院统一信息平台(单点登录测试)_第2张图片
首页

点击“这里”,跳转服务端的登录页面
SpringBoot实例:医院统一信息平台(单点登录测试)_第3张图片
登录页

选择一种登录方式后,进入授权页面
SpringBoot实例:医院统一信息平台(单点登录测试)_第4张图片
授权

许可后点击确认并授权,完成后进入hello页面
SpringBoot实例:医院统一信息平台(单点登录测试)_第5张图片
hello

你可能感兴趣的:(SpringBoot实例:医院统一信息平台(单点登录测试))