diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2015-12-01 15:10:30 +1300 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2015-12-01 15:10:30 +1300 |
commit | 77b9194cc963645fc9ccf7ce79280982cead8f0f (patch) | |
tree | f85b038a5b40ecbe334bd7864656af7c59204866 /src/org/traccar/api | |
parent | 0e5e61fd14486e6b926b83895eedf9c97c2cb342 (diff) | |
download | traccar-server-77b9194cc963645fc9ccf7ce79280982cead8f0f.tar.gz traccar-server-77b9194cc963645fc9ccf7ce79280982cead8f0f.tar.bz2 traccar-server-77b9194cc963645fc9ccf7ce79280982cead8f0f.zip |
Refactor security request filtering
Diffstat (limited to 'src/org/traccar/api')
-rw-r--r-- | src/org/traccar/api/AuthorizationBasic.java | 98 | ||||
-rw-r--r-- | src/org/traccar/api/SecurityRequestFilter.java | 77 | ||||
-rw-r--r-- | src/org/traccar/api/UserPrincipal.java | 36 | ||||
-rw-r--r-- | src/org/traccar/api/UserSecurityContext.java (renamed from src/org/traccar/api/SecurityContextApi.java) | 13 |
4 files changed, 42 insertions, 182 deletions
diff --git a/src/org/traccar/api/AuthorizationBasic.java b/src/org/traccar/api/AuthorizationBasic.java deleted file mode 100644 index 291d0e5d6..000000000 --- a/src/org/traccar/api/AuthorizationBasic.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.api; - -import java.sql.SQLException; -import java.util.List; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TreeSet; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.core.MultivaluedMap; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.handler.codec.base64.Base64; -import org.jboss.netty.util.CharsetUtil; -import org.traccar.Context; -import org.traccar.model.User; - -public final class AuthorizationBasic { - - private AuthorizationBasic() { - } - - public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String AUTHORIZATION_SCHEME_VALUE = "Basic"; - public static final String REGEX = AUTHORIZATION_SCHEME_VALUE + " "; - public static final String REPLACEMENT = ""; - public static final String TOKENIZER = ":"; - public static final String USERNAME = "username"; - public static final String PASSWORD = "password"; - public static final String WWW_AUTHENTICATE_VALUE = "Basic realm=\"api\""; - - public static UserPrincipal getUserPrincipal(ContainerRequestContext requestContext) { - final MultivaluedMap<String, String> headers = requestContext.getHeaders(); - final List<String> authorization = headers.get(AUTHORIZATION_HEADER); - if (authorization == null || authorization.isEmpty()) { - return null; - } - final String encodedUsernameAndPassword = authorization.get(0).replaceFirst(REGEX, REPLACEMENT); - ChannelBuffer buffer = ChannelBuffers.copiedBuffer(encodedUsernameAndPassword, CharsetUtil.UTF_8); - String usernameAndPassword = Base64.decode(buffer).toString(CharsetUtil.UTF_8); - final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, TOKENIZER); - String username = tokenizer.nextToken(); - String password = tokenizer.nextToken(); - Set<String> roles = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - UserPrincipal userPrincipal = new UserPrincipal(username, password, roles); - return userPrincipal; - } - - public static boolean isAuthenticatedUser(UserPrincipal userPrincipal) { - if (userPrincipal.getName() != null && userPrincipal.getPassword() != null) { - User user; - try { - user = Context.getDataManager().login(userPrincipal.getName(), userPrincipal.getPassword()); - } catch (SQLException e) { - return false; - } - if (user != null) { - userPrincipal.setId(user.getId()); - /* - for (Role role : user.getRoles()) { - userPrincipal.getRoles().add(role.getName()); - } - */ - - //Temporary solution - userPrincipal.getRoles().add(User.ROLE_USER); - if (user.getAdmin()) { - userPrincipal.getRoles().add(User.ROLE_ADMIN); - } - return true; - } - } - return false; - } - - public static boolean isAuthorizedUser(UserPrincipal userPrincipal, Set<String> roles) { - for (String role : roles) { - if (userPrincipal.getRoles().contains(role)) { - return true; - } - } - return false; - } -} diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java index e9d285f9b..b1e090487 100644 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -15,67 +15,46 @@ */ package org.traccar.api; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import javax.annotation.security.DenyAll; -import javax.annotation.security.PermitAll; -import javax.annotation.security.RolesAllowed; +import org.traccar.Context; +import org.traccar.model.User; + +import java.sql.SQLException; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Response; +import javax.xml.bind.DatatypeConverter; public class SecurityRequestFilter implements ContainerRequestFilter { - private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - private static final String BASIC_REALM = "Basic realm=\"api\""; + public static final String AUTHORIZATION_HEADER = "Authorization"; + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + public static final String BASIC_REALM = "Basic realm=\"api\""; - @javax.ws.rs.core.Context - private ResourceInfo resourceInfo; + public static String[] decodeBasicAuth(String auth) { + auth = auth.replaceFirst("[B|b]asic ", ""); + byte[] decodedBytes = DatatypeConverter.parseBase64Binary(auth); + if (decodedBytes != null && decodedBytes.length > 0) { + return new String(decodedBytes).split(":", 2); + } + return null; + } @Override public void filter(ContainerRequestContext requestContext) { - Method method = resourceInfo.getResourceMethod(); - - if (method.isAnnotationPresent(PermitAll.class)) { - return; - } - - if (method.isAnnotationPresent(DenyAll.class)) { - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build()); - return; - } - - UserPrincipal userPrincipal = AuthorizationBasic.getUserPrincipal(requestContext); - if (userPrincipal == null - || userPrincipal.getName() == null - || userPrincipal.getPassword() == null - || !isAuthenticatedUser(userPrincipal)) { - requestContext.abortWith( - Response.status(Response.Status.UNAUTHORIZED).header(WWW_AUTHENTICATE, BASIC_REALM).build()); - return; - } - - if (method.isAnnotationPresent(RolesAllowed.class)) { - RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class); - Set<String> roles = new HashSet<>(Arrays.asList(rolesAnnotation.value())); - if (!isAuthorizedUser(userPrincipal, roles)) { - requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build()); - return; + try { + String[] auth = decodeBasicAuth(requestContext.getHeaderString(AUTHORIZATION_HEADER)); + User user = Context.getDataManager().login(auth[0], auth[1]); + if (user != null) { + requestContext.setSecurityContext( + new UserSecurityContext(new UserPrincipal(user.getId(), user.getName()))); + } else { + throw new WebApplicationException( + Response.status(Response.Status.UNAUTHORIZED).header(WWW_AUTHENTICATE, BASIC_REALM).build()); } + } catch (SQLException e) { + throw new WebApplicationException(e); } - - requestContext.setSecurityContext(new SecurityContextApi(userPrincipal)); - } - - private boolean isAuthenticatedUser(UserPrincipal principal) { - return AuthorizationBasic.isAuthenticatedUser(principal); - } - - private boolean isAuthorizedUser(UserPrincipal userPrincipal, Set<String> roles) { - return AuthorizationBasic.isAuthorizedUser(userPrincipal, roles); } } diff --git a/src/org/traccar/api/UserPrincipal.java b/src/org/traccar/api/UserPrincipal.java index 11a6de629..d858b6f47 100644 --- a/src/org/traccar/api/UserPrincipal.java +++ b/src/org/traccar/api/UserPrincipal.java @@ -16,44 +16,24 @@ package org.traccar.api; import java.security.Principal; -import java.util.Set; public class UserPrincipal implements Principal { - private Long id; - private String username; - private String password; - private Set<String> roles; + private String name; + private long userId; - public UserPrincipal(String username, String password, Set<String> roles) { - this.username = username; - this.password = password; - this.roles = roles; + public UserPrincipal(long userId, String name) { + this.userId = userId; + this.name = name; } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; + public Long getUserId() { + return userId; } @Override public String getName() { - return username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Set<String> getRoles() { - return roles; + return name; } } diff --git a/src/org/traccar/api/SecurityContextApi.java b/src/org/traccar/api/UserSecurityContext.java index 38ce7e33d..127aee4b3 100644 --- a/src/org/traccar/api/SecurityContextApi.java +++ b/src/org/traccar/api/UserSecurityContext.java @@ -18,23 +18,22 @@ package org.traccar.api; import java.security.Principal; import javax.ws.rs.core.SecurityContext; -public class SecurityContextApi implements SecurityContext { +public class UserSecurityContext implements SecurityContext { - private Principal userPrincipal; + private UserPrincipal principal; - public SecurityContextApi(Principal userPrincipal) { - this.userPrincipal = userPrincipal; + public UserSecurityContext(UserPrincipal principal) { + this.principal = principal; } @Override public Principal getUserPrincipal() { - return userPrincipal; + return principal; } @Override public boolean isUserInRole(String role) { - UserPrincipal user = (UserPrincipal) userPrincipal; - return user.getRoles().contains(role); + return true; } @Override |