简体   繁体   English

错误 404:javax.servlet.ServletException:java.io.FileNotFoundException:SRVE0190E:找不到文件:/oidcclient/redirect/MyRP

[英]Error 404: javax.servlet.ServletException: java.io.FileNotFoundException: SRVE0190E: File not found: /oidcclient/redirect/MyRP

I am trying to integrate AppID service with my spring application.我正在尝试将 AppID 服务与我的 spring 应用程序集成。 For that I have added redirect-uri https://app-host-name:port-number/oidcclient/redirect/MyRP under MyAppId service -> Management -> Authentication Settings for the purpose of redirecting back to the application after authenticating user credentials.为此,我在 MyAppId 服务 -> 管理 -> 身份验证设置下添加了 redirect-uri https://app-host-name:port-number/oidcclient/redirect/MyRP ,以便在验证用户凭据后重定向回应用程序.

Now the problem is that when user tries to sign into the application after entering credentials then it is not getting redirecting to uri that I have specified in my application code, instead giving 404 code mentioned in subject.现在的问题是,当用户在输入凭据后尝试登录应用程序时,它不会重定向到我在应用程序代码中指定的 uri,而是给出主题中提到的 404 代码。

Please go through the below specified code particular to AppID implementataion part and suggest me some solution to this problem.请 go 通过以下特定于 AppID 实现部分的指定代码,并建议我解决此问题。

Following is the technology stack of application:-以下是应用程序的技术栈:-

1.Spring (4.3.0.RELEASE)
2.Spring Security (4.1.1.RELEASE)
3.Websphere Liberty (20.0.0.1)

I have implemented integration code as per IBM Official code repository for AppID on https://github.com/ibm-cloud-security/app-id-sample-java我已经按照 IBM Official code repository for AppID on https://github.com/ibm-cloud-security/app-id-sample-java实现了集成代码

Changes done in application code are as follows:-应用程序代码中所做的更改如下:-

server.xml服务器.xml

<!-- Enable features -->
<featureManager>
    <feature>jsp-2.3</feature>
    <feature>localConnector-1.0</feature>
    <!-- Features for APP ID -->
    <feature>servlet-3.1</feature>
    <feature>appSecurity-2.0</feature>
    <feature>openidConnectClient-1.0</feature>
    <feature>ssl-1.0</feature>
</featureManager>

<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
              
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true" startTimeout="15m"/>


<applicationMonitor updateTrigger="mbean"/>

<keyStore id="defaultKeyStore" password="${keystore_password}"/>
<keyStore id="digicertRootCA" location="${server.config.dir}/resources/security/digicert-root-ca.jks" password="digicert"/>
<ssl id="oidcClientSSL" keyStoreRef="defaultKeyStore" trustStoreRef="digicertRootCA"/>



  <authFilter id="myAuthFilter">
    <requestUrl id="myRequestUrl" urlPattern="/appid_callback" matchType="contains"/>
</authFilter>


<openidConnectClient id="MyRP"
                     clientId="${env.APP_ID_CLIENT_ID}"
                     clientSecret= "${env.APP_ID_CLIENT_SECRET}"
                     authorizationEndpointUrl="${env.APP_ID_OAUTH_SERVER_URL}/authorization"
                     tokenEndpointUrl="${env.APP_ID_OAUTH_SERVER_URL}/token"
                     jwkEndpointUrl="${env.APP_ID_OAUTH_SERVER_URL}/publickeys"
                     issuerIdentifier="${env.APP_ID_ISSUER_IDENTIFIER}"
                     tokenEndpointAuthMethod="basic"
                     signatureAlgorithm="RS256"
                     authFilterid="myAuthFilter"
                     redirectToRPHostAndPort="https://${env.APP_ID_HOSTNAME}.${env.APP_ID_DOMAIN}"
/> 
 
<application id="ne" location="ne-1.0.0-BUILD-SNAPSHOT.war" name="ne">
    <application-bnd>
        <security-role name="appidrole">
                    <special-subject type="ALL_AUTHENTICATED_USERS" />
        </security-role>
    </application-bnd>
 </application>  
 

web.xml web.xml

<web-app 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
version="3.1">

<display-name>MyWebApp</display-name>

<security-role>
    <role-name>appidrole</role-name>
</security-role>

<servlet>
    <servlet-name>AppIdCallbackServlet</servlet-name>
    <servlet-class>com.example.appid.AppIdCallBackServlet</servlet-class>
</servlet>

<servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>com.example.appid.AppIdLogoutServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>AppIdCallbackServlet</servlet-name>
    <url-pattern>/appid_callback</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/logout</url-pattern>
</servlet-mapping>

<security-constraint>
    <display-name>Security Constraints</display-name>
    <web-resource-collection>
        <web-resource-name>Security Constraint</web-resource-name>
        <url-pattern>/appid_callback/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>PUT</http-method>
        <http-method>POST</http-method>
        <http-method>DELETE</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>appidrole</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
</security-constraint>

<!-- <filter>
    <filter-name>FilterToGetTimeOut </filter-name> 
    <filter-class>example.common.filter.FilterToGetTimeOut </filter-class> 
</filter>
<filter-mapping> 
    <filter-name>FilterToGetTimeOut</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> -->

<session-config>
    <session-timeout>20</session-timeout>
</session-config>   

Mapping映射

@RequestMapping(value="/", method=RequestMethod.GET)
public String appidCallbackMapping(HttpServletRequest request, HttpServletResponse response)
{
    logger.info("present in appid callback mapping method created in UserController.java ===> deepanshu.l@hcl.com");
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    String idTokenRaw = null;
    try {
        idTokenRaw = getIDToken();
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    logger.info("calling getIdToken before checking whether auth object instanceof AnonymousAuthenticationToken ===> deepanshu.l@hcl.com");
    logger.info("idToken Value :- " + idTokenRaw);
    if (!(auth instanceof AnonymousAuthenticationToken)) {
        logger.info("authentication object found not to be an instance of AnonymousAuthenticationToken (successfully )===> deepanshu.l@hcl.com");
         try {
             idTokenRaw = getIDToken();
             logger.info("inside check of AnonymousAuthenticationToken --> tokenValue ===> " + idTokenRaw);
             if (idTokenRaw != null) {
                    String idTokenPayload = getTokenPayload(idTokenRaw);
                    // save the id_token and user's name on the request so that
                    // they can be passed on to UI elements
                    JSONObject idTokenContent = JSONObject.parse(idTokenPayload);
                    String username = idTokenContent.get("name").toString();
                    logger.info("Username value retrieved from appid token :- " + username);
                //    request.setAttribute("name", username);
                //   request.setAttribute("id_token", idTokenPayload);
                } else {
                    logger.info("No id_token located via security context");
                }
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
         UserDetails userDetail=null;
         userDetail = (UserDetails) auth.getPrincipal();
         ObjectMapper objectMapper = new ObjectMapper();
         try {
            logger.info(objectMapper.writeValueAsString(auth));
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
         String userId= userDetail.getUsername();
         
        logger.info("User Id of the user as follows :- " + userId); 
        return "redirect:/company";
    }
    else
        return "redirect:/appid_callback";
                
}

   private String getIDToken() throws IOException{
    Subject wasSubj;
    try {
        wasSubj = WSSubject.getRunAsSubject();
    } catch (WSSecurityException e) {
        // In real applications, exception should be handled better
        throw new IOException(e);
    }

    Set<Hashtable> creds = wasSubj.getPrivateCredentials(Hashtable.class);

    for (Hashtable hTable : creds) {
        if (hTable.containsKey("id_token")) {
            return hTable.get("id_token").toString();
        }
    }
    //return null if not found
    return null;
}

 private String getTokenPayload(String token) {
        String payload64 = token.split("\\.")[1];
        String payload = new String(Base64.decodeBase64(payload64));
        return payload;
    }

AppIdCallBackServlet.java AppIdCallBackServlet.java

public class AppIdCallBackServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

private final static Logger logger = LogManager.getLogger(FileUploadController.class);

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    logger.info("present in doGet nethod of appIdCallback method ==> deepanshu.l@hcl.com");
    
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();
    try {
        String idTokenRaw = getIDToken();
        if (idTokenRaw != null) {
            String idTokenPayload = getTokenPayload(idTokenRaw);
            // save the id_token and user's name on the request so that
            // they can be passed on to UI elements
            JSONObject idTokenContent = JSONObject.parse(idTokenPayload);
            String username = idTokenContent.get("name").toString();
            logger.info("username value retrieved from token and currently present in AppIdCallbackServlet.java file ===> " + username);
            request.setAttribute("name", username);
            request.setAttribute("id_token", idTokenPayload);
        } else {
            out.println("No id_token located via security context");
        }
    } catch (Exception e) {
        // In real applications, exception should be handled better
        e.printStackTrace(out);
    }
    request.getRequestDispatcher("/").forward(request, response);
}

private String getTokenPayload(String token) {
    String payload64 = token.split("\\.")[1];
    String payload = new String(Base64.decodeBase64(payload64));
    return payload;
}

/*
This method uses Liberty API to extract a Hashtable object that contains
the App ID tokens.
 */
private String getIDToken() throws IOException{
    Subject wasSubj;
    try {
        wasSubj = WSSubject.getRunAsSubject();
    } catch (WSSecurityException e) {
        // In real applications, exception should be handled better
        throw new IOException(e);
    }

    Set<Hashtable> creds = wasSubj.getPrivateCredentials(Hashtable.class);

    for (Hashtable hTable : creds) {
        if (hTable.containsKey("id_token")) {
            return hTable.get("id_token").toString();
        }
    }
    //return null if not found
    return null;
}
  }

SecurityConfig.java安全配置.java

  @Override 
  protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests().antMatchers("/**").permitAll();
  }

In server.xml instead of <keyStore id="defaultKeyStore" password="${keystore_password}"/> <keyStore id="digicertRootCA" location="${server.config.dir}/resources/security/digicert-root-ca.jks" password="digicert"/> <ssl id="oidcClientSSL" keyStoreRef="defaultKeyStore" trustStoreRef="digicertRootCA"/>在 server.xml 而不是<keyStore id="defaultKeyStore" password="${keystore_password}"/> <keyStore id="digicertRootCA" location="${server.config.dir}/resources/security/digicert-root-ca.jks" password="digicert"/> <ssl id="oidcClientSSL" keyStoreRef="defaultKeyStore" trustStoreRef="digicertRootCA"/>

Try using <keyStore id="defaultKeyStore" password="${keystore_password}"/> <ssl id="oidcClientSSL" keyStoreRef="defaultKeyStore" trustDefaultCerts="true" />尝试使用<keyStore id="defaultKeyStore" password="${keystore_password}"/> <ssl id="oidcClientSSL" keyStoreRef="defaultKeyStore" trustDefaultCerts="true" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM