aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/api
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2015-12-01 15:10:30 +1300
committerAnton Tananaev <anton.tananaev@gmail.com>2015-12-01 15:10:30 +1300
commit77b9194cc963645fc9ccf7ce79280982cead8f0f (patch)
treef85b038a5b40ecbe334bd7864656af7c59204866 /src/org/traccar/api
parent0e5e61fd14486e6b926b83895eedf9c97c2cb342 (diff)
downloadtraccar-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.java98
-rw-r--r--src/org/traccar/api/SecurityRequestFilter.java77
-rw-r--r--src/org/traccar/api/UserPrincipal.java36
-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