Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 保护SpringRESTfulWebServiceAPI不受未经授权的访问?_Android_Web Services_Spring Mvc_Spring Security - Fatal编程技术网

Android 保护SpringRESTfulWebServiceAPI不受未经授权的访问?

Android 保护SpringRESTfulWebServiceAPI不受未经授权的访问?,android,web-services,spring-mvc,spring-security,Android,Web Services,Spring Mvc,Spring Security,我已经用不同的API成功地创建了一个SpringRESTfulWebService。现在我应该保护它们不被未经授权的访问。我遵循了,登录逻辑与我的完全不同。有人能帮我继续前进吗 获取用户登录请求 处理用户登录请求 我有用于获取国家/地区、用户列表等的API。这些服务应该只在用户有效后向Android客户端提供数据。我知道身份验证将使用访问令牌进行处理。我怎样才能用标准的方式来做呢?我认为您需要有一个单独的流程来授权设备在您的应用程序中使用 我曾经开发过一个应用程序,其中平板电脑注册使用一个应用程

我已经用不同的API成功地创建了一个SpringRESTfulWebService。现在我应该保护它们不被未经授权的访问。我遵循了,登录逻辑与我的完全不同。有人能帮我继续前进吗

获取用户登录请求

处理用户登录请求


我有用于获取国家/地区、用户列表等的API。这些服务应该只在用户有效后向Android客户端提供数据。我知道身份验证将使用访问令牌进行处理。我怎样才能用标准的方式来做呢?

我认为您需要有一个单独的流程来授权设备在您的应用程序中使用

我曾经开发过一个应用程序,其中平板电脑注册使用一个应用程序。tablet ID保存在Apache服务器可以访问的简单文本文件中。然后,所有REST请求都有一个特殊的头X_DEVICEID,其中包含设备ID,Apache使用的PHP脚本检查文件中的该ID,并且仅当ID是注册设备的ID时才会给出响应

允许的设备ID文件充当某种防火墙来阻止未注册的设备

您可以通过更改登录名来遵循上述教程本身 服务中的逻辑。在服务中定义自定义身份验证服务
spring security.xml

通常,一个简单的支持Spring安全性的应用程序将使用 作为身份验证源的简单用户服务:

最后,在
spring security.xml
中,您可以过滤受保护的URL 如下



好吧,为了保护这样一个API(例如登录),您需要两件事:一是csrf令牌,以防止跨站点请求伪造。这基本上是一个crump,一个随机服务器生成的字符串,作为登录页面上的隐藏表单字段输出。当您提交登录表单时,服务器将验证此csrf令牌,以检查它是否与其生成的令牌相同。这些都是短暂的——大约5分钟。你需要的另一件事是拥有一个共享的秘密,该秘密被应用程序用来获取一个短期访问令牌。访问令牌应该是一次性的。因此,您需要注册一个用户。你有他们的电子邮件地址(比如说)。用户现在使用您的登录API登录,您可以通过加密一些数据并对其进行base64编码来生成访问令牌,例如HMAC(电子邮件地址+用户的创建时间戳,共享机密)。了解hmac。它使用共享对称密钥。您需要与用户共享此对称密钥-一种方法是在用户注册后向他们发送一封带有此密钥的电子邮件。问得好。我一直在浏览。请允许任何人对此提供答案。@Farhad。我知道身份验证将通过使用访问令牌进行处理。我也知道其逻辑。但我如何以标准方式进行?请注意,spring security是标准化的方式。我们必须采用相同的方式。非常感谢您的精彩回答:)
 @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public UserResponse login(@RequestBody final UserLoginRequest userRequest) throws ServletException, IOException {
        UserResponse userResponse = new UserResponse();
        try {
            userResponse = accessService.login(userRequest);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return userResponse;
    }
 @Transactional
    public UserResponse login(UserLoginRequest userRequest) throws SQLException,
            ClassNotFoundException, IOException {
        UserResponse userResponse = new UserResponse();

        int status = 0;

        //boolean isExist = loginDao.isUserExist(userRequest.getUsername(), userRequest.getPassword());
        User user = loginDao.getUser(userRequest.getEmailID());
        if (user != null) {
            if (userRequest.getPassword().equals(user.getPassword())) {//Case sensitive password and added to check status
                //User exist
                if (user.getStatus().equals("1")) {
                    //Device token check
                    loginDao.isDeviceTokenExists(userRequest, user.getProfileId());

                    status = 2;
                } else {
                    status = 3;
                }
            } else {
                status = 4;
            }
        } else {
            status = 1;
        }
        if (status == 1) {
            userResponse.setCode(WeekenterConstants.USER_EMAIL_EXIST_CODE);
            userResponse.setMessage("User does not exists.Please Register.");
        } else if (status == 2) {
            userResponse.setCode(WeekenterConstants.SUCCESS_CODE);
            userResponse.setMessage("User login success");
            userResponse.setId(user.getProfileId());
        } else if (status == 3) {
            userResponse.setCode(WeekenterConstants.FAILURE_CODE);
            userResponse.setMessage("Your Account is blocked. Please contact Weekenter administrator.");
            userResponse.setId(user.getProfileId());
        } else if (status == 4) {
            userResponse.setCode(WeekenterConstants.FAILURE_CODE);
            userResponse.setMessage("Password is wrong.");
            userResponse.setId(user.getProfileId());
        }
        return userResponse;
    }
<!--Custom User details service which is provide the user data-->
<bean id="customUserDetailsService"
          class="com.yourpackage.CustomUserDetailsService" />

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="customUserDetailsService" />
</authentication-manager>
import com.weekenter.www.dao.LoginDao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private LoginDao loginDao;

    public UserDetails loadUserByUsername(String login)
            throws UsernameNotFoundException {

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;
        com.weekenter.www.entity.User user = null;
        try {
            user = loginDao.getUser(login);//login variable contain your requested username 
            if (user != null) {
                if (user.getStatus().equals("1")) {
                    enabled = false;
                }
            } else {
                throw new UsernameNotFoundException(login + " Not found !");
            }

        } catch (Exception ex) {
            try {
                throw new Exception(ex.getMessage());
            } catch (Exception ex1) {
            }
        }

 <!-- Password comparison will happen here -->
        return new User(
                user.getEmail(),
                user.getPassword(),
                enabled,
                accountNonExpired,
                credentialsNonExpired,
                accountNonLocked,
                getAuthorities()
        );
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles());
        return authList;
    }

    public List<String> getRoles() {
        List<String> roles = new ArrayList<String>();
        roles.add("ROLE_APP");
        return roles;
    }

    public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }

}
<!-- This is where we tells spring security what URL should be protected 
    and what roles have access to them -->
    <http pattern="/api/**" create-session="never"
              entry-point-ref="oauthAuthenticationEntryPoint"
              access-decision-manager-ref="accessDecisionManager"
              xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/api/**" access="ROLE_APP" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>