Обеспечение безопасности веб-службы JAX-RS - PullRequest
0 голосов
/ 31 декабря 2018

Наш проект реализован с использованием приложения WAS Server 8.5 / Struts 2.

javax.ws.rs.core.SecurityContext - это просто интерфейс.Что можно использовать, как показано ниже.

@javax.ws.rs.GET
@javax.ws.rs.Path("/{abc}")
@javax.ws.rs.Produces(MediaType.APPLICATION_XML)
@Secured
public List<Object> getReport(@PathParam("abc") String abc,@Context SecurityContext securityContext) {
          System.out.println("securityContext.isSecure() "+securityContext.isSecure());
          if(securityContext.isSecure()!=true){
                 throw new SecurityException("User is unauthorized.");
          }
   }

Мой файл конфигурации сервлета выглядит следующим образом.

    <servlet>
        <servlet-name>JAXRSRestConfig</servlet-name>
        <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.ubs.gsp.rest.RestWebAppConfig</param-value>
        </init-param>
        <init-param>
            <param-name>javax.ws.rs.container.ContainerRequestFilter</param-name>
            <param-value>com.ubs.gsp.rest.AuthenticationFilter</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   <security-constraint>
        <web-resource-collection>
            <web-resource-name>RestWebServiceResource</web-resource-name>
            <url-pattern>/rest/*</url-pattern>
        </web-resource-collection>
        <!-- <auth-constraint>
        <role-name>ADMIN</role-name>
        </auth-constraint> -->
        <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <login-config>
    <auth-method>BASIC</auth-method>
    </login-config>
    <servlet-mapping>
        <servlet-name>JAXRSRestConfig</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

Класс AuthenticationFilter:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    @Context
    private ResourceInfo resourceInfo;

    private static final String AUTHORIZATION_PROPERTY = "Authorization";
    private static final String AUTHENTICATION_SCHEME = "Basic";
    private static final Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED)
                                                        .entity("You cannot access this resource").build();
    private static final Response ACCESS_FORBIDDEN = Response.status(Response.Status.FORBIDDEN)
                                                        .entity("Access blocked for all users !!").build();
    @Override
    public void filter(ContainerRequestContext requestContext)
    {
        System.out.println("filter ContainerRequestContext");
        Method method = resourceInfo.getResourceMethod();
        //Access allowed for all
        if( ! method.isAnnotationPresent(PermitAll.class))
        {
            //Access denied for all
            if(method.isAnnotationPresent(DenyAll.class))
            {
                requestContext.abortWith(ACCESS_FORBIDDEN);
                return;
            }

            //Get request headers
            final MultivaluedMap<String, String> headers = requestContext.getHeaders();

            //Fetch authorization header
            final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);

            //If no authorization information present; block access
            if(authorization == null || authorization.isEmpty())
            {
                requestContext.abortWith(ACCESS_DENIED);
                return;
            }

            //Get encoded username and password
            final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
            //Decode username and password
            //String usernameAndPassword = new String(Base64.decode(encodedUserPassword.getBytes()));;
            String usernameAndPassword = new String(Base64.decode(encodedUserPassword));;
            //Split username and password tokens
            final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
            final String username = tokenizer.nextToken();
            final String password = tokenizer.nextToken();

            //Verifying Username and password
            System.out.println(username);
            System.out.println(password);

            //Verify user access
            if(method.isAnnotationPresent(RolesAllowed.class))
            {
                RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
                Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));

                //Is user valid?
                if( ! isUserAllowed(username, password, rolesSet))
                {
                    requestContext.abortWith(ACCESS_DENIED);
                    return;
                }
            }
        }
    }
    private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet)
    {
        System.out.println("filter isUserAllowed");

        boolean isAllowed = false;

        //Step 1. Fetch password from database and match with password in argument
        //If both match then get the defined role for user from database and continue; else return isAllowed [false]
        //Access the database and do this part yourself
        //String userRole = userMgr.getUserRole(username);

        if(username.equals("password") && password.equals("password"))
        {
            isAllowed = true;
        }
        return isAllowed;
    }
}

Весь код, связанный с аутентификациейпереходит в класс AuthenticationFilter.

Мне нужна идея регистрации AuthenticationFilter в нашем проекте.

При каждом вызове метода getReport () AuthenticationFilter должен быть перехвачен в целях безопасности.Как это сделать?

Любая помощь действительно приветствуется !!

...