Spring Securityを使ってICを統合して単点登録を完了します。

14009 ワード

一、企業単一登録(CAS)
1.Java(Spring Webflow/MVC servlet)サーバコンポーネント
2.挿抜可能認証サポート(LDAP、データベース、X.509、ダブル要因)
3.複数のプロトコル(CAS、SAML、OAuth、OpenID)をサポートします。
4.プラットフォームをまたぐクライアントサポート(Java,Net,PHP,Perl,Apacheなど)
5.uPortal、Liferay、BlueSocket、MoodleとGoogle Appsと統合して、いくつかの例を挙げます。
CAS            ,         。                 ,         500               。
二、どのようにCASを配置しますか?
プロジェクトにCASサーバーをインストールするには、CAS標準WARファイルを公式githubにダウンロードしてWARファイルに標準的なシングルポイントがあります。もちろん、deployer ConfigContectxt.xmlでAuthentication Handlerを指定して簡単に変更する必要があります。CAS自体はAuthentication Handlerが多く含まれており、対応する問題の解決に協力できます。
CASサーバ自体以外のキーはもちろん、企業に展開されるセキュリティWebアプリケーションであり、これらのWebアプリケーションは「サービス」と呼ばれています。三つのタイプのサービスがあります。サービスチケットを検証し、プロキシチケットを獲得し、プロキシの検証を行うことができます。プロキシリストが検証され、通常はプロキシを再利用することができます。
CAS自体はHTTPS環境において、ローカルテスト及び個人学習の場合に、CASに対してHTTPアクセスをサポートするように修正できます。CASのWARファイルカタログ:WEB-INF\classies/servicesでHTTPSAAPS-100000 1.jsonプロファイルを修正し、serviceId属性の値を変更します。
"serviceId":"^(https|imaps|http)://.*"
CAS 4.2バージョンの後、CASのすべての構成はcas.propertiesファイルに配置されていますので、cas.propertiesをカスタマイズできるように、WEB-INF\spring-configration\propertyFileConfigrer.xmlファイルの変更ができます。

CASがデータベースを通じてユーザー証明書を確認できるようにするためには、Database Authenticationを設定する必要があります。公式文書の詳細は以下の通りです。https://apereo.github.io/cas/4.2.x/installation/Database-Authentication.htmlデータベース認証には4つの種類があります。
1.QueryDatabaseAuthenticationHandler,              。
   cas.properties   :
# cas.jdbc.authn.query.sql=select password from users where username=?
 deployerConfigContext.xml   



2.SearchModeSearchDatabaseAuthenticationHandler,                 ;             ,      。
   cas.properties   
# cas.jdbc.authn.search.password=
# cas.jdbc.authn.search.user=
# cas.jdbc.authn.search.table=
 deployerConfigContext.xml   



 3.BindModeSearchDatabaseAuthenticationHandler,        (  )                   。
 deployerConfigContext.xml   



4.QueryAndEncodeDatabaseAuthenticationHandler,  JDBC      ,            salt ,     salt        。               。             。
   cas.properties   
# cas.jdbc.authn.query.encode.sql=
# cas.jdbc.authn.query.encode.alg=
# cas.jdbc.authn.query.encode.salt.static=
# cas.jdbc.authn.query.encode.password=    
# cas.jdbc.authn.query.encode.salt=    
# cas.jdbc.authn.query.encode.iterations.field=    
# cas.jdbc.authn.query.encode.iterations=
 deployerConfigContext.xml   


第4のデータ認証方式を選択し、修正が完了したらtomcatで実行すればいいです。casのアクセスアドレス:ip:port/cas/login casの登録住所:ip:port/cas/logout
三、Spring SecurityとCASの集積
Webブラウザ、CASサーバとSpringセキュリティサービスの基本的なインタラクションは以下の通りです。
CASまたはSpring Securityは、パブリックページの処理を管理しないで、ユーザーが安全なページまたはそれが使用する安全なページを要求すると、Spring SecurityのException Translation Filterは、Access DeniedExceptionまたはAuthentication Exceptionを検出します。
ユーザのAuthenticationオブジェクト(または不足)がAuthentication Exceptionをもたらすので、Exception Translation Filterは、設定されたAuthentication EntryPointを呼び出します。CASを使用すると、Cas Authentication EntryPointクラスになります。
Cas Authentication EntryPointはユーザーのブラウザをCASサーバにリダイレクトします。また、Spring SecurityサービスのリダイレクトURLとして表示されます。例えば、ブラウザリダイレクトのURLは
https://my.company.com/cas/login?service= HTTPS%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin / CAS。
ユーザーのブラウザがCASにリダイレクトされると、システムはユーザーにユーザー名とパスワードの入力を促す。ユーザーが以前にログインしたことを示すセッションクッキーを提出すると、再登録を提示されなくなります。CASは上記のPasswodHandler(またはCAS 3.0を使用したAuthentication Handler)を使用します。を選択して、ユーザー名とパスワードが有効かどうかを決定します。
CASのログインが成功すると、ユーザブラウザを元のサービスにリダイレクトします。また、手形パラメータも含まれます。これは不透明な文字列です。「サービスチケット」を表します。前の例を続けると、ブラウザがリダイレクトされるURLは
https://server3.company.com/webapp/login/cas?ticket=ST-0-ER94xMJmn6pha35CQRoZ。
サービスWebアプリケーションに戻ると、Cas AuthenticationFilterは常に/login/casの要求を傍受します(これは構成可能ですが、この紹介のデフォルト値を使用します)。を選択します。処理フィルタは、サービス手形を表すUsernamePassword Authentication Tokenに相当します。本体は、Cas Authentication Filter.C.AS_STATEFUL_IDENTIFIERに相当します。証明書はサービスチケットの不透明値です。この認証要求は、設定されたAuthenticationManagerに渡されます。
AuthenticationManagerの実現はProvider Managerとなり、Cas Authentication Providerがまた配置されています。Cas Authentication Providerは、CAS特定の主体(Cas Authentication Filter.caster.CasAustatFUID ENTIFIER)とCas Authentication Tokenのみに応答します。
Cas AuthenticationProviderは、TicketValidatorを使用してサービスチケットを検証します。これは通常、CASクライアントライブラリに含まれている種類のCas 20 ServiceTicketValidatorです。アプリケーションが代理券を検証する必要があるなら、Cas 20 ProxyTicketValidaterを使用します。TickValidatorは、HTSサーバにも検証を要求します。この例に含まれているプロキシフィードバックURLを含みます。
https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin/cas&ticket= ST-0-ER94xMJmn6pha35CQRoZ&pgtUrl = HTTPS://server3.company.com/webapp/login/cas/proxyreceptor。
CASサーバに戻ると、認証要求が受信されます。提供されたサービスチケットが発行チケットのサービスURLと一致すると、CASはXMLでユーザ名の肯定応答を表します。どのプロキシも認証に参加すると(以下に説明します)、プロキシリストもXML応答に含まれます。
[オプション]CAS認証サービスに対する要求がプロキシコールURLを含む場合(pgtUrlパラメータにおいて)CASは、XML応答にpgtIou文字列を含んでいます。このpgtIouは、エージェント付与票を表しています。そして、CASサーバは、自分のHTTPSを作成してpgtUrlに接続します。これは、CASサーバと主張するサービスURLを相互認証するためです。HTTPS接続は、ライセンスチケットの代理を元のWebアプリケーションに送信します。例えば、
  https://server3.company.com/webapp/login/cas/proxyreceptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH。
Cas 20 TicketValidatorはCASサーバから受信したXMLを解析します。これはCas Authentication Provider TicketResponseに戻ります。ここにはユーザー名(強制)が含まれています。エージェントリスト(もし何かあれば)とチケット証明書IOUに代理付与されます。
次に、CasAuthenticationProviderは、配置されたCasProxyDeciderを呼び出します。CasProxyDeciderは、TicketReponseのプロキシリストがサービスされるかどうかを指示します。Spring Securityは、いくつかの実装を提供しています。信頼されたプロキシのリストを提供します。
Cas AuthenticationProviderは次にAssionに適用されるユーザに適用されるGranced AuthortyオブジェクトをロードするAuthentication UserDetails erviceを要求します。問題がなければ、Cas Authentication ProviderはCas Authentication Tokenを構築します。TicketResonseとGrantication Authortsの詳細が含まれます。
制御は次にCas AuthenticationFilterに戻り、それはCas AuthenticationTokenを作成して安全なコンテキストに置く。
ユーザのブラウザは、Authentication Exceptionの元のページ(または構成によるカスタムターゲット)にリダイレクトされる。
四、Spring Boot+Spring Security+CAS開発(代理手形認証)
Cas Authentication Providerは、状態クライアントと無状態クライアントを区別しています。状態のあるクライアントは、Cas Authentication Filterのfilter ProcesssUrlに提出されたと考えられています。無状態クライアントは、FilterProcessUrl以外のURLを指して、CasAuthentication Filterにアイデンティティ検証要求を提出する任意のクライアントを指します。
リモートプロトコルは、HttpSessionのコンテキストでは提示できないので、要求間のセッションにセキュリティコンテキストを格納するデフォルトの実践に依存することはできない。また、CASサーバは、TicketValidator検証後に無効にするため、後続の要求において同じエージェントチケット証明を表示することは機能しない。
CasConfing配置://クライアント配置public static String cas ServiceHost="http://127.0.0.1:8080「;public static String casServiceLogin=casServiceHost+」/login/cas";public static String casServiceLogout=casServiceHost+"/logout/cas";public static String casServiceProxyCarlet;public static String casServiceFailure Handler="cas/cas failed"
//cas     
@Value("${cas.server.host:http://127.0.0.1:8081/cas}")
public static String casServerUrlPrefix="http://127.0.0.1:8081/cas";
public static String casServerUrlLogin=casServerUrlPrefix+"/login";
public static String casServerUrlLogout=casServerUrlPrefix+"/logout";

@Autowired
public static ProxyGrantingTicketStorageImpl pgtStorage;

@Bean
public ServiceProperties serviceProperties(){
    ServiceProperties serviceProperties=new ServiceProperties();
    serviceProperties.setService(casServiceLogin);
    serviceProperties.setAuthenticateAllArtifacts(true);
    return serviceProperties;
}

@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint(@Qualifier("serviceProperties") ServiceProperties serviceProperties){
    CasAuthenticationEntryPoint entryPoint=new CasAuthenticationEntryPoint();
    entryPoint.setServiceProperties(serviceProperties);
    entryPoint.setLoginUrl(casServerUrlLogin);

    return entryPoint;
}

@Bean("pgtStorage")
public ProxyGrantingTicketStorageImpl proxyGrantingTicketStorageImpl(){
    return new ProxyGrantingTicketStorageImpl();
}

@Bean("casAuthenticationProvider")
public CasAuthenticationProvider casAuthenticationProvider(@Qualifier("serviceProperties") ServiceProperties serviceProperties,
        @Qualifier("customCasUserDetailsService") CustomCasUserDetailsService customCasUserDetailsService){
    CasAuthenticationProvider authenticationProvider=new CasAuthenticationProvider();
    authenticationProvider.setKey("casProvider") ;
    authenticationProvider.setServiceProperties(serviceProperties);
    Cas20ProxyTicketValidator ticketValidator=new Cas20ProxyTicketValidator(casServerUrlPrefix);
    ticketValidator.setAcceptAnyProxy(true);//          
    ticketValidator.setProxyGrantingTicketStorage(pgtStorage);
    authenticationProvider.setTicketValidator(ticketValidator);
    authenticationProvider.setAuthenticationUserDetailsService(customCasUserDetailsService);
    //     
    EhCacheBasedTicketCache ticketCache=new EhCacheBasedTicketCache();
    ticketCache.setCache(new Cache("casTickets", 50, true, false, 3600, 900));
    authenticationProvider.setStatelessTicketCache(ticketCache);
    
    return authenticationProvider;
}

//    ,           
@Bean("requestSingleLogoutFilter")
public LogoutFilter logoutFilter() {
    LogoutFilter logoutFilter = new LogoutFilter(casServerUrlLogout, new SecurityContextLogoutHandler());
    logoutFilter.setFilterProcessesUrl(casServiceLogout);
    return logoutFilter;
}
Web SecurityCas Config配置:
    @Autowired
CasAuthenticationProvider casAuthenticationProvider;

@Autowired
CasAuthenticationEntryPoint casAuthenticationEntryPoint;

@Autowired
LogoutFilter requestSingleLogoutFilter;

@Autowired
ServiceProperties serviceProperties;
    
public CasAuthenticationFilter casAuthenticationFilter() throws Exception{
    CasAuthenticationFilter casAuthenticationFilter=new CasAuthenticationFilter();
    casAuthenticationFilter.setAuthenticationManager(authenticationManager());
    casAuthenticationFilter.setServiceProperties(serviceProperties);
    casAuthenticationFilter.setProxyGrantingTicketStorage(CasConfing.pgtStorage);
    casAuthenticationFilter.setProxyReceptorUrl(CasConfing.casServiceProxyCallbackUrl);
    casAuthenticationFilter.setAuthenticationDetailsSource(new ServiceAuthenticationDetailsSource(serviceProperties));
    casAuthenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(CasConfing.casServiceFailureHandler));

    return casAuthenticationFilter;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    // TODO Auto-generated method stub
    http
    .authorizeRequests()
    .antMatchers("/cas/casfailed").permitAll()
    .antMatchers("/secure/extreme/").access("hasRole('ROLE_SUPERVISOR')")
    .antMatchers("/secure/**").access("hasRole('ROLE_USER')")
    .anyRequest().authenticated()
    .and()
    .logout()
    .logoutUrl("/logout/cas")
    .logoutSuccessUrl(CasConfing.casServerUrlLogout+"?service="+CasConfing.casServiceHost+"/index")
    .permitAll()
    .and()
    .csrf().disable();

    //CAS        
    SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
    singleSignOutFilter.setCasServerUrlPrefix(CasConfing.casServerUrlPrefix);
    http
    .exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint)
    .and()
    .addFilter(casAuthenticationFilter())
    .addFilterBefore(requestSingleLogoutFilter, LogoutFilter.class)
    .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class);
}


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // TODO Auto-generated method stub
    auth.authenticationProvider(casAuthenticationProvider);
    super.configure(auth);
}
CustoomCasUserDetails Serviceカスタム認証ユーザ情報処理構成:
@Service
public class CutomCas UserDetails Service implements Authentication UserDetails Service{
@Override
public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
    // TODO Auto-generated method stub
    System.err.println("          :"+token.getName());
    List grantedAuthorities = new ArrayList<>();
    GrantedAuthority grantedAuthority=new SimpleGrantedAuthority("ROLE_SUPERVISOR");
    grantedAuthorities.add(grantedAuthority);
    grantedAuthority=new SimpleGrantedAuthority("ROLE_USER");
    grantedAuthorities.add(grantedAuthority);
    
    return new User(token.getName(), "a52302c58f4a60f49b1ad2f36add6d0a-000000", grantedAuthorities);
}
)
ここでSpring Security+CAS統合構成が完成しました。
          Security    :
http://127.0.0.1:8080/index,
security   CAS       
http://127.0.0.1:8081/cas/login?service=http%3A%2F%2F127.0.0.1%3A8080%2Flogin%2Fcas
               。

   :
        :serviceCas01,serviceCas02
 http://127.0.0.1:8080/serviceCas01/index,
 http://127.0.0.1:8082/serviceCas02/index,
serviceCas01       ,        http://127.0.0.1:8082/serviceCas02/index,        。  http://127.0.0.1:8080/serviceCas01/logout/cas     ,        http://127.0.0.1:8082/serviceCas02/index,    。
続きは時間があります。また図を作ります。足りないところは教えてください。
  :  
            ,