可选的kerberos认证?

问题描述 投票:6回答:4

是否可以进行可选的kerberos认证?

我想要的是:如果客户端(浏览器)不在域名上,它将被重定向到用户名密码网页登录。否则它将做SPNEGO做Kerberos认证。

有什么办法可以解决这个问题吗?如果有,我们需要哪些配置?

kerberos spring-security-kerberos
4个回答
3
投票

是的,你可以这样做。当服务器接收到一个未经认证的请求时,它会用401("需要授权")来回复,这是一个头。WWW-Authenticate 设为 Negotiate. 如果 Kerberos 认证失败,服务器也会发回一个 401 页面。

每当客户端认证失败时(例如,没有任何 Kerberos 凭证,或者认证失败),就会显示 401 页面内容。

所以,要解决你的问题,你要做的就是在401页面中包含登录页面。


0
投票

如果你需要在服务器收到一个未认证的请求后重定向到登录页面(就像Elias Mårtenson说的那样),你需要像这样配置spring security。

springSecurity.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:sec="http://www.springframework.org/schema/security"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

<sec:http entry-point-ref="spnegoEntryPoint" >
    <sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
    <sec:form-login login-page="/login.xhtml" default-target-url="/index.xhtml" />
    <sec:access-denied-handler error-page="/login.xhtml" />
</sec:http>

<bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider ref="kerberosServiceAuthenticationProvider" /> <!-- Used with SPNEGO -->
    <sec:authentication-provider ref="kerberosAuthenticationProvider"/> <!-- Used with form login -->
</sec:authentication-manager>

<bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
    <property name="kerberosClient">
        <bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
            <property name="debug" value="true"/>
        </bean>
    </property>
    <property name="userDetailsService" ref="customUserDetailsService"/>
</bean>

<bean id="kerberosServiceAuthenticationProvider" class="ru.rfcfefa.epod.common.base.interceptor.CustomKerberosServiceAuthenticationProvider">
    <property name="ticketValidator">
        <bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
            <property name="servicePrincipal" value="HTTP/serverName.domain.local" />
            <!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
            <!-- See the Javadoc for more information on that -->
            <property name="keyTabLocation" value="http-server.keytab" />
            <property name="debug" value="true" />
        </bean>
    </property>
    <property name="userDetailsService" ref="customUserDetailsService" />
</bean>

<bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
    <property name="debug" value="true" />
    <property name="krbConfLocation" value="krb5.conf"/>
</bean>
</beans>

krb5.conf

[libdefaults]
    default_realm = DOMAIN.LOCAL
    default_tkt_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    default_tgs_enctypes = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc
    permitted_enctypes   = aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc

[realms]
    DOMAIN.LOCAL  = {
        kdc = serverAD.domain.local 
        default_domain = DOMAIN.LOCAL
}

[domain_realm]
     .DOMAIN.LOCAL = DOMAIN.LOCAL

  • HTTPserverName.domain.local--服务主名。
  • http-server.keytab - 生成的keytab文件 ( 见 MIKE WIESNER博客Lior Chaga的经验)
  • 要小心 keyTabLocation 属性,它不是指向.keytab文件的路径,而是指向.keytab文件的URL,所以要用 文件。 找到
  • krbConfLocation - kerberos 配置文件的路径。krb5.conf 在您的系统上
  • customUserDetailsService - 您的自定义详细服务。
  • 不要忘记设置属性 调试 在生产中改为假的

0
投票

如果你使用的是Apache,那么 签名 模块可以通过在 (普通的、带内的 auth) 登录页面上使用一些 JavaScript 来实现这一点, 并在登录控制器上使用第二个路径来实现 Kerberos 验证。 常规 "登录表单会测试对 Kerberos 保护的资源的访问是否成功,如果成功,则重定向浏览器自动完成登录。

在我看来,上面的做法似乎有点落后,而且在没有严格必要的情况下增加一个 JavaScript 要求是令人反对的。 我认为Elias Mårtenson的回答是正确的--尝试使用Kerberos,然后在HTTP 401响应中回到带内登录--但这是否可行取决于你的环境。


0
投票

你需要提供网络地址范围,AD 的用户将使用该地址,并实现你自己的 SpnegoEntryPoint 实现,如下图。

public class CustomSpnegoEntryPoint extends SpnegoEntryPoint {

  private Logger logger = //TODO add  logger    

  private final String forwardUrl; //for example you custom login page /login

  private final String ssoDomainNetworkAddress; //e.g. 192.168.0.1/16 

  public CustomSpnegoEntryPoint(String forwardUrl, String ssoDomainNetworkAddress) {
    super(forwardUrl);
    this.forwardUrl = forwardUrl;
    this.ssoDomainNetworkAddress = ssoDomainNetworkAddress;
  }

  @Override
  public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {

    if(userBelongsToDomain(request)) {
      //do sso magic and send handshake Negotiate
      super.commence(request, response, ex);
    } else {
      //redirect to login page
      RequestDispatcher dispatcher = request.getRequestDispatcher(forwardUrl);
      dispatcher.forward(request, response);
    }
  }

  private boolean userBelongsToDomain(HttpServletRequest request) {
    try {
      SubnetUtils.SubnetInfo subnetInfo = new SubnetUtils(ssoDomainNetworkAddress).getInfo();
      return subnetInfo.isInRange(request.getRemoteAddr());
    } catch (IllegalArgumentException ex) {
      logger.warn("Address is invalid. Use  CIDR-notation string, e.g. '192.168.0.1/16'", ex);
      return false;
    }
  }
}

然后将其添加到WebSecurityConfig中。

http
          .exceptionHandling()
          .authenticationEntryPoint(new CustomSpnegoEntryPoint(
              "/login",
              "192.168.0.1/16")); // or from application.properties

当用户的地址来自于域,并且配置了正确的浏览器时,SSO就会工作。当请求来自公共地址(非内网)时,服务器会强制重定向到登录页面。

希望对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.